Content
# 🚀 Google Drive MCP Server
<p align="center">
[](https://www.python.org/downloads/)
[](https://fastapi.tiangolo.com/)
[](https://github.com/starlite-api/fastmcp)
[](LICENSE)
[](tests/)
</p>
A production-ready **Model Context Protocol (MCP) server** for Google Drive operations with **OAuth2 multi-user support**. Use AI coding assistants (OpenCode, Cline, Cursor, etc.) to manage Google Drive files through natural language.
## 🤔 What is MCP?
MCP (Model Context Protocol) is a standardized protocol that lets AI tools communicate with external services. Instead of writing code, you can tell your AI assistant to:
- "List my Google Drive files"
- "Upload this report to Drive"
- "Find all PDFs in my Drive"
And the AI will use the MCP tools automatically!
---
## ✨ Features
- **6 Google Drive Operations** via MCP:
| Tool | Description |
|------|-------------|
| `list_files` | List files with pagination |
| `upload_file` | Upload files (auto-resumable for large files) |
| `download_file` | Download files (streaming for 100MB+) |
| `delete_file` | Delete files permanently |
| `search_files` | Full-text + name search |
| `get_file_metadata` | Get file details |
- **Multi-User OAuth2 Authentication**:
- Users authenticate with their own Google accounts
- Each user gets isolated access to their own Drive
- Automatic token refresh
- Session-based authentication
- **Hybrid Auth (Optional)**:
- OAuth2 (recommended): Per-user authentication
- Service Account: Backward-compatible single-account mode
- **Production-Ready**:
- ✅ Exponential backoff with jitter (rate-limit resilience)
- ✅ Bearer token authentication (API_KEY or session token)
- ✅ Health check endpoints (`/health`, `/ready`)
- ✅ SQLite database for OAuth tokens
- ✅ Docker multi-stage build
- ✅ Deploy to Render with zero config
---
## 🚀 Quick Start
### Prerequisites
- Python 3.11+
- Google Cloud Platform account (free)
- Git
### Option 1: OAuth2 (Recommended)
Users authenticate with their own Google accounts.
#### Step 1: Set Up Google OAuth (10 min)
1. Go to [Google Cloud Console](https://console.cloud.google.com)
2. Create or select a project
3. **Enable Google Drive API**: Search "Google Drive API" → Enable
4. **Create OAuth Credentials**:
- Go to APIs & Services → Credentials
- Click "Create Credentials" → OAuth client ID
- Application type: **Web application**
- Authorized redirect URIs: `https://yourdomain.com/auth/callback`
- Authorized JavaScript origins: `https://yourdomain.com`
5. Copy **Client ID** and **Client Secret**
#### Step 2: Generate Encryption Key
```bash
python -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())"
```
#### Step 3: Run Server
```bash
# Clone
git clone https://github.com/himanshu231204/google-drive-mcp.git
cd google-drive-mcp
# Create virtual environment
python -m venv venv
# Windows: venv\Scripts\activate
# Mac/Linux: source venv/bin/activate
# Install
pip install -r requirements.txt
# Set environment variables
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"
# Run
uvicorn app.main:app --host 0.0.0.0 --port 10000 --reload
```
---
### Option 2: Service Account (Legacy)
Uses a single service account for all users (all users share the same Drive access).
#### Step 1: Get Google Service Account (5 min)
1. Go to [console.cloud.google.com](https://console.cloud.google.com)
2. Create or select a project
3. **Enable Google Drive API**: Search "Google Drive API" → Enable
4. **Create Service Account**:
- IAM & Admin → Service Accounts → Create
- Name: `google-drive-mcp` → Create → Continue → Done
5. **Create JSON Key**: Click service account → Keys → Add Key → JSON
> 📁 **Important**: Share Drive folders with your service account email (e.g., `google-drive-mcp@project.iam.gserviceaccount.com`) so it can access them.
#### Step 2: Run Server
```bash
# Set environment variables
export GOOGLE_CREDENTIALS_JSON='{"type":"service_account",...}' # One line!
export API_KEY="your-secure-key"
# Run
uvicorn app.main:app --host 0.0.0.0 --port 10000 --reload
```
---
## 🔌 How to Use with AI Assistants
### OpenCode
Add to your `.opencode/config.json`:
```json
{
"mcpServers": {
"GoogleDrive": {
"type": "remote",
"url": "https://your-server.onrender.com/mcp",
"headers": {
"Authorization": "Bearer YOUR_SESSION_TOKEN"
}
}
}
}
```
### Cline / Cursor / Other MCP Clients
```json
{
"mcpServers": {
"google-drive": {
"url": "https://your-server.onrender.com/mcp",
"type": "remote",
"auth": {
"type": "bearer",
"token": "YOUR_SESSION_TOKEN"
}
}
}
}
```
### OAuth Login Flow
1. Visit `/auth/login` to get OAuth authorization URL
2. User redirects to Google and authorizes
3. Google redirects to `/auth/callback` with auth code
4. Server exchanges code for tokens and sets session cookie
5. Use session token in MCP requests
### Example AI Prompts
Once connected, try these prompts:
```
"Can you list the files in my Google Drive?"
"Please upload this document to my Drive, folder 'Reports'"
"Find all PDF files in my Drive that contain 'invoice'"
"Download the file with ID abc123 and tell me its size"
"Can you get the metadata for that presentation file?"
```
---
## 🧪 Testing the MCP Server
### Health Check
```bash
curl http://localhost:10000/health
```
### OAuth Status
```bash
curl http://localhost:10000/auth/status
```
### Direct MCP Tool Call
```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 Documentation
Visit http://localhost:10000/docs for interactive API docs.
---
## 🌐 Deploy to Render (Free)
### One-Click Deploy
1. Push code to GitHub
2. Go to [render.com/new](https://render.com/new)
3. Select "Web Service"
4. Connect your GitHub repo
5. Configure:
- **Runtime**: Python 3.11
- **Build Command**: `pip install -r requirements.txt`
- **Start Command**: `uvicorn app.main:app --host 0.0.0.0 --port $PORT`
6. **Add Environment Variables**:
#### For OAuth2:
- `GOOGLE_CLIENT_ID` = your OAuth client ID
- `GOOGLE_CLIENT_SECRET` = your OAuth client secret
- `GOOGLE_REDIRECT_URI` = `https://your-app.onrender.com/auth/callback`
- `ENCRYPTION_KEY` = your Fernet encryption key
#### For Service Account (optional):
- `GOOGLE_CREDENTIALS_JSON` = your service account JSON
- `API_KEY` = your secure key
7. Deploy!
---
## 📚 MCP Tool Reference
### list_files
List files in a folder with pagination.
```python
list_files(folder_id: str = None, page_size: int = 50, page_token: str = None)
```
### upload_file
Upload a file (auto-resumable for large files).
```python
upload_file(file_path: str, folder_id: str = None, resumable: bool = True)
```
### download_file
Download a file (streams for files >100MB).
```python
download_file(file_id: str, output_path: str = None)
```
### delete_file
Permanently delete a file.
```python
delete_file(file_id: str)
```
### search_files
Search files by name or content.
```python
search_files(query: str, limit: int = 50)
```
### get_file_metadata
Get detailed file information.
```python
get_file_metadata(file_id: str)
```
---
## 🔐 OAuth API Endpoints
| Endpoint | Method | Description |
|----------|--------|-------------|
| `/auth/login` | GET | Get OAuth authorization URL |
| `/auth/callback` | GET | Handle OAuth callback |
| `/auth/logout` | POST | Logout current user |
| `/auth/me` | GET | Get current user info |
| `/auth/status` | GET | Check authentication status |
---
## ⚙️ Environment Variables
### OAuth2 Mode (Recommended)
| Variable | Required | Description |
|----------|----------|-------------|
| `GOOGLE_CLIENT_ID` | ✅ Yes | OAuth client ID from Google Cloud Console |
| `GOOGLE_CLIENT_SECRET` | ✅ Yes | OAuth client secret |
| `GOOGLE_REDIRECT_URI` | ✅ Yes | OAuth callback URL |
| `ENCRYPTION_KEY` | ✅ Yes | Fernet key for encrypting tokens (generate with `python -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())"`) |
| `PORT` | No | Server port (default: 10000) |
| `LOG_LEVEL` | No | DEBUG, INFO, WARNING, ERROR |
| `CORS_ORIGINS` | No | Comma-separated allowed origins |
### Service Account Mode (Legacy)
| Variable | Required | Description |
|----------|----------|-------------|
| `GOOGLE_CREDENTIALS_JSON` | ✅ Yes | Service account JSON (one line) |
| `API_KEY` | ✅ Yes | Bearer token for auth |
| `PORT` | No | Server port (default: 10000) |
| `LOG_LEVEL` | No | DEBUG, INFO, WARNING, ERROR |
| `CORS_ORIGINS` | No | Comma-separated allowed origins |
---
## 🐛 Troubleshooting
| Error | Fix |
|-------|-----|
| `GOOGLE_CLIENT_ID not set` | Set OAuth credentials in environment |
| `ENCRYPTION_KEY not set` | Generate with `python -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())"` |
| `GOOGLE_CREDENTIALS_JSON not set` | Set service account JSON (Service Account mode) |
| `401 Unauthorized` | Check session token or API_KEY in Bearer header |
| `OAuth callback error` | Check GOOGLE_REDIRECT_URI matches Google Cloud Console |
| `403 Permission denied` | For Service Account: share Drive folder with service account email |
| `429 Too Many Requests` | Wait; server auto-retries with backoff |
---
## 📁 Project Structure
```
google-drive-mcp/
├── app/
│ ├── main.py # FastAPI app entry point
│ ├── mcp_server.py # FastMCP 6 tools
│ ├── drive_service.py # Google Drive API wrapper
│ ├── auth.py # Service account auth
│ ├── schemas.py # Pydantic models
│ ├── utils.py # Helpers
│ ├── oauth/
│ │ ├── handlers.py # OAuth2 logic
│ │ └── routes.py # OAuth endpoints
│ └── database/
│ ├── models.py # SQLAlchemy models
│ └── __init__.py # Database session
├── tests/ # 69 unit tests
│ └── test_oauth.py # OAuth tests
├── .github/workflows/ # CI/CD
├── requirements.txt # Dependencies
├── Dockerfile # Container build
├── render.yaml # Render config
└── README.md # This file
```
---
## 🤝 Contributing
See [CONTRIBUTING.md](CONTRIBUTING.md) for how to contribute.
## 📄 License
MIT License - see [LICENSE](LICENSE).
---
## 👤 Author
**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>
---
**Built with** ❤️ **using Python + FastAPI + FastMCP + OAuth2**
MCP Config
Below is the configuration for this MCP Server. You can copy it directly to Cursor or other MCP clients.
mcp.json
Connection Info
You Might Also Like
No recommendations available