内容
# 🚀 Google Drive 中转服务器
<p align="center">
[](https://www.python.org/downloads/)
[](https://fastapi.tiangolo.com/)
[](https://github.com/starlite-api/fastmcp)
[](LICENSE)
[](tests/)
</p>
一款适用于 Google Drive 操作的生产就绪型 **模型上下文协议(MCP)服务器**,支持 **OAuth2 多用户身份验证**。使用 AI 编程助手(OpenCode、Cline、Cursor 等)通过自然语言管理 Google Drive 文件。
## 🤔 什么是 MCP?
MCP(模型上下文协议)是一种标准化协议,允许 AI 工具与外部服务通信。您无需编写代码,而是可以告诉 AI 助手:
- “列出我的 Google Drive 文件”
- “将此报告上传到 Drive”
- “在我的 Drive 中查找所有 PDF 文件”
AI 将自动使用 MCP 工具!
---
## ✨ 功能
- **6种 Google Drive 操作** 通过 MCP:
| 工具 | 描述 |
|------|-------------|
| `list_files` | 列出文件,支持分页 |
| `upload_file` | 上传文件(自动支持大文件断点续传) |
| `download_file` | 下载文件(支持 100MB 以上文件流式下载) |
| `delete_file` | 永久删除文件 |
| `search_files` | 全文 + 名称搜索 |
| `get_file_metadata` | 获取文件详情 |
- **多用户 OAuth2 身份验证**:
- 用户使用自己的 Google 账户进行身份验证
- 每个用户对其自己的 Drive 都具有隔离的访问权限
- 自动令牌刷新
- 基于会话的身份验证
- **混合身份验证(可选)**:
- OAuth2(推荐):每个用户的身份验证
- 服务账户:向后兼容的单账户模式
- **生产就绪**:
- ✅ 具有抖动的指数退避(速率限制弹性)
- ✅ 持有者令牌身份验证(API_KEY 或会话令牌)
- ✅ 健康检查端点(`/health`,`/ready`)
- ✅ 用于 OAuth 令牌的 SQLite 数据库
- ✅ Docker 多阶段构建
- ✅ 部署到 Render,无需配置
---
## 🚀 快速开始
### 前置条件
- Python 3.11+
- Google Cloud Platform 账户(免费)
- Git
### 选项 1:OAuth2(推荐)
用户使用自己的 Google 账户进行身份验证。
#### 步骤 1:设置 Google OAuth(10 分钟)
1. 访问 [Google Cloud Console](https://console.cloud.google.com)
2. 创建或选择一个项目
3. **启用 Google Drive API**:搜索“Google Drive API”→ 启用
4. **创建 OAuth 凭证**:
- 进入 API 和服务 → 凭证
- 点击“创建凭证”→ OAuth 客户端 ID
- 应用程序类型:**Web 应用程序**
- 授权重定向 URI:`https://yourdomain.com/auth/callback`
- 授权 JavaScript 来源:`https://yourdomain.com`
5. 复制 **客户端 ID** 和 **客户端密钥**
#### 步骤 2:生成加密密钥
```bash
python -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())"
```
#### 步骤 3:运行服务器
```bash
# 克隆
git clone https://github.com/himanshu231204/google-drive-mcp.git
cd google-drive-mcp
# 创建虚拟环境
python -m venv venv
# Windows: venv\Scripts\activate
# Mac/Linux: source venv/bin/activate
# 安装
pip install -r requirements.txt
# 设置环境变量
export GOOGLE_CLIENT_ID="your-client-id"
export GOOGLE_CLIENT_SECRET="your-client-secret"
export GOOGLE_REDIRECT_URI="https://yourdomain.com/auth/callback"
export ENCRYPTION_KEY="your-encryption-key-from-step-2"
# 运行
uvicorn app.main:app --host 0.0.0.0 --port 10000 --reload
```
---
### 选项 2:服务账户(旧版)
使用单个服务账户为所有用户(所有用户共享相同的 Drive 访问权限)。
#### 步骤 1:获取 Google 服务账户(5 分钟)
1. 访问 [console.cloud.google.com](https://console.cloud.google.com)
2. 创建或选择一个项目
3. **启用 Google Drive API**:搜索“Google Drive API”→ 启用
4. **创建服务账户**:
- IAM 和管理 → 服务账户 → 创建
- 名称:`google-drive-mcp` → 创建 → 继续 → 完成
5. **创建 JSON 密钥**:点击服务账户 → 密钥 → 添加密钥 → JSON
> 📁 **重要**:与您的服务账户电子邮件(例如 `google-drive-mcp@project.iam.gserviceaccount.com`)共享 Drive 文件夹,以便它可以访问它们。
#### 步骤 2:运行服务器
```bash
# 设置环境变量
export GOOGLE_CREDENTIALS_JSON='{"type":"service_account",...}' # 一行!
export API_KEY="your-secure-key"
# 运行
uvicorn app.main:app --host 0.0.0.0 --port 10000 --reload
```
---
## 🔌 如何与 AI 助手一起使用
### OpenCode
添加到您的 `.opencode/config.json` 中:
```json
{
"mcpServers": {
"GoogleDrive": {
"type": "remote",
"url": "https://your-server.onrender.com/mcp",
"headers": {
"Authorization": "Bearer YOUR_SESSION_TOKEN"
}
}
}
}
```
### Cline / Cursor / 其他 MCP 客户端
```json
{
"mcpServers": {
"google-drive": {
"url": "https://your-server.onrender.com/mcp",
"type": "remote",
"auth": {
"type": "bearer",
"token": "YOUR_SESSION_TOKEN"
}
}
}
}
```
### OAuth 登录流程
1. 访问 `/auth/login` 获取 OAuth 授权 URL
2. 用户重定向到 Google 并授权
3. Google 重定向到 `/auth/callback`,并带有授权码
4. 服务器交换代码以获取令牌并设置会话 cookie
5. 在 MCP 请求中使用会话令牌
### 示例 AI 提示
连接后,尝试这些提示:
```
“你能列出我的 Google Drive 文件吗?”
“请将此文档上传到我的 Drive,文件夹‘Reports’”
“在我的 Drive 中查找所有包含‘invoice’的 PDF 文件”
“下载 ID 为 abc123 的文件,并告诉我它的大小”
“你能获取那个演示文稿文件的文件元数据吗?”
```
---
## 🧪 测试 MCP 服务器
### 健康检查
```bash
curl http://localhost:10000/health
```
### OAuth 状态
```bash
curl http://localhost:10000/auth/status
```
### 直接 MCP 工具调用
```bash
curl -X POST http://localhost:10000/mcp \
-H "Authorization: Bearer YOUR_SESSION_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "list_files",
"arguments": {}
}
}'
```
### API 文档
访问 http://localhost:10000/docs 获取交互式 API 文档。
---
## 🌐 部署到 Render(免费)
### 一键部署
1. 将代码推送到 GitHub
2. 访问 [render.com/new](https://render.com/new)
3. 选择“Web 服务”
4. 连接您的 GitHub 仓库
5. 配置:
- **运行时**:Python 3.11
- **构建命令**:`pip install -r requirements.txt`
- **启动命令**:`uvicorn app.main:app --host 0.0.0.0 --port $PORT`
6. **添加环境变量**:
#### 对于 OAuth2:
- `GOOGLE_CLIENT_ID` = 您的 OAuth 客户端 ID
- `GOOGLE_CLIENT_SECRET` = 您的 OAuth 客户端密钥
- `GOOGLE_REDIRECT_URI` = `https://your-app.onrender.com/auth/callback`
- `ENCRYPTION_KEY` = 您的 Fernet 加密密钥
#### 对于服务账户(可选):
- `GOOGLE_CREDENTIALS_JSON` = 您的服务账户 JSON
- `API_KEY` = 您的安全密钥
7. 部署!
---
## 📚 MCP 工具参考
### list_files
列出文件夹中的文件,支持分页。
```python
list_files(folder_id: str = None, page_size: int = 50, page_token: str = None)
```
### upload_file
上传文件(自动支持大文件断点续传)。
```python
upload_file(file_path: str, folder_id: str = None, resumable: bool = True)
```
### download_file
下载文件(支持 100MB 以上文件流式下载)。
```python
download_file(file_id: str, output_path: str = None)
```
### delete_file
永久删除文件。
```python
delete_file(file_id: str)
```
### search_files
按名称或内容搜索文件。
```python
search_files(query: str, limit: int = 50)
```
### get_file_metadata
获取文件详细信息。
```python
get_file_metadata(file_id: str)
```
---
## 🔐 OAuth API 端点
| 端点 | 方法 | 描述 |
|----------|--------|-------------|
| `/auth/login` | GET | 获取 OAuth 授权 URL |
| `/auth/callback` | GET | 处理 OAuth 回调 |
| `/auth/logout` | POST | 注销当前用户 |
| `/auth/me` | GET | 获取当前用户信息 |
| `/auth/status` | GET | 检查身份验证状态 |
---
## ⚙️ 环境变量
### OAuth2 模式(推荐)
| 变量 | 必需 | 描述 |
|----------|----------|-------------|
| `GOOGLE_CLIENT_ID` | ✅ 是 | 来自 Google Cloud Console 的 OAuth 客户端 ID |
| `GOOGLE_CLIENT_SECRET` | ✅ 是 | OAuth 客户端密钥 |
| `GOOGLE_REDIRECT_URI` | ✅ 是 | OAuth 回调 URL |
| `ENCRYPTION_KEY` | ✅ 是 | 用于加密令牌的 Fernet 密钥(使用 `python -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())"` 生成) |
| `PORT` | 否 | 服务器端口(默认:10000) |
| `LOG_LEVEL` | 否 | DEBUG, INFO, WARNING, ERROR |
| `CORS_ORIGINS` | 否 | 以逗号分隔的允许来源列表 |
### 服务账户模式(旧版)
| 变量 | 必需 | 描述 |
|----------|----------|-------------|
| `GOOGLE_CREDENTIALS_JSON` | ✅ 是 | 服务账户 JSON(一行) |
| `API_KEY` | ✅ 是 | 身份验证的持有者令牌 |
| `PORT` | 否 | 服务器端口(默认:10000) |
| `LOG_LEVEL` | 否 | DEBUG, INFO, WARNING, ERROR |
| `CORS_ORIGINS` | 否 | 以逗号分隔的允许来源列表 |
---
## 🐛 故障排除
| 错误 | 修复方法 |
|-------|-----|
| `GOOGLE_CLIENT_ID not set` | 在环境中设置 OAuth 凭证 |
| `ENCRYPTION_KEY not set` | 使用 `python -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())"` 生成 |
| `GOOGLE_CREDENTIALS_JSON not set` | 设置服务账户 JSON(服务账户模式) |
| `401 Unauthorized` | 在持有者头部检查会话令牌或 API_KEY |
| `OAuth callback error` | 检查 GOOGLE_REDIRECT_URI 是否与 Google Cloud Console 匹配 |
| `403 Permission denied` | 对于服务账户:与服务账户电子邮件共享 Drive 文件夹 |
| `429 Too Many Requests` | 等待;服务器自动重试并带有退避 |
---
## 📁 项目结构
```
google-drive-mcp/
├── app/
│ ├── main.py # FastAPI 应用入口
│ ├── mcp_server.py # FastMCP 6 种工具
│ ├── drive_service.py # Google Drive API 包装器
│ ├── auth.py # 服务账户身份验证
│ ├── schemas.py # Pydantic 模型
│ ├── utils.py # 帮助程序
│ ├── oauth/
│ │ ├── handlers.py # OAuth2 逻辑
│ │ └── routes.py # OAuth 端点
│ └── database/
│ ├── models.py # SQLAlchemy 模型
│ └── __init__.py # 数据库会话
├── tests/ # 69 个单元测试
│ └── test_oauth.py # OAuth 测试
├── .github/workflows/ # CI/CD
├── requirements.txt # 依赖项
├── Dockerfile # 容器构建
├── render.yaml # Render 配置
└── README.md # 本文件
```
---
## 🤝 贡献
参见 [CONTRIBUTING.md](CONTRIBUTING.md) 了解如何贡献。
## 📄 许可证
MIT 许可证 - 参见 [LICENSE](LICENSE)。
---
## 👤 作者
**Himanshu** (@himanshu231204)
<p align="left">
<a href="https://github.com/himanshu231204">
<img src="https://img.shields.io/badge/GitHub-himanshu231204-181717?style=flat&logo=github" alt="GitHub">
</a>
<a href="https://linkedin.com/in/himanshu231204">
<img src="https://img.shields.io/badge/LinkedIn-himanshu231204-0077B5?style=flat&logo=linkedin" alt="LinkedIn">
</a>
<a href="https://twitter.com/himanshu231204">
<img src="https://img.shields.io/badge/Twitter-himanshu231204-1DA1F2?style=flat&logo=twitter" alt="Twitter">
</a>
</p>
---
**使用 ** ❤️ **Python + FastAPI + FastMCP + OAuth2** 构建**