Google Docs & Gmail MCP Server
README.md
# Google Docs & Gmail MCP Server
A complete Model Context Protocol (MCP)-style server in Python using **FastAPI** that integrates directly with **Google Docs** and **Gmail** via the official Google APIs with OAuth 2.0 authentication and **interactive terminal-based human-in-the-loop approval**.
---
## ๐ Project Structure
```
google-mcp-server/
โโโ server.py โ FastAPI app with tool endpoints & terminal confirmation
โโโ auth.py โ Google OAuth 2.0 authentication & token persistence
โโโ docs_tool.py โ Google Docs tool (appends content to docs)
โโโ gmail_tool.py โ Gmail tool (creates email drafts)
โโโ requirements.txt โ Python package dependencies
โโโ .gitignore โ Prevents committing credentials.json & token.json
โโโ Procfile โ Railway / PaaS process declaration
โโโ railway.toml โ Railway build & healthcheck configuration
โโโ Dockerfile โ Container definition for cloud deployments
โโโ deployment.md โ Detailed Railway cloud deployment guide
โโโ README.md โ Setup, configuration, and usage instructions
โโโ credentials.json โ (NOT committed โ downloaded from Google Cloud Console)
โโโ token.json โ (NOT committed โ auto-generated after first OAuth login)
```
---
## โ๏ธ Features
1. **Google OAuth 2.0 Authentication (`auth.py`)**:
- Scopes configured:
- `https://www.googleapis.com/auth/documents` (Google Docs read/write)
- `https://www.googleapis.com/auth/gmail.compose` (Gmail draft creation)
- Automatically loads existing `token.json` without re-opening the browser.
- Automatically refreshes expired tokens.
- Automatically launches browser-based OAuth consent flow on initial run and writes `token.json`.
2. **Google Docs Tool (`docs_tool.py`)**:
- `append_to_doc(doc_id: str, content: str)`
- Appends text content to the end of any Google Doc using the official Google Docs API v1 (`documents.batchUpdate`).
3. **Gmail Tool (`gmail_tool.py`)**:
- `create_email_draft(to: str, subject: str, body: str)`
- Creates a new draft message in the authenticated user's Gmail using the official Gmail API v1 (`users.drafts.create`).
4. **FastAPI Server with Human-in-the-loop Approval (`server.py`)**:
- `POST /append_to_doc`: Appends text to a document.
- `POST /create_email_draft`: Creates an email draft.
- **Terminal Gatekeeper**: Before executing any tool action, the server outputs the action name and exact payload to the console and asks:
```text
============================================================
โ ๏ธ [ACTION PENDING APPROVAL]: append_to_doc
------------------------------------------------------------
Payload:
{
"doc_id": "1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms",
"content": "New analysis findings..."
}
============================================================
Approve? (y/n):
```
- Typing **`y`** (or `Y`) approves and executes the action.
- Typing **`n`** (or any other input) rejects the action and returns `403 Forbidden` with a rejection notification to the caller.
---
## ๐ Setup & Installation
### 1. Prerequisites
- Python 3.9+
- A Google Account with access to [Google Cloud Console](https://console.cloud.google.com/)
---
### 2. Google Cloud Setup & Credentials
1. Go to the [Google Cloud Console](https://console.cloud.google.com/).
2. Create a new project (e.g., `google-mcp-server`).
3. Enable the required APIs:
- Search for **Google Docs API** and click **Enable**.
- Search for **Gmail API** and click **Enable**.
4. Configure the **OAuth Consent Screen**:
- Go to **APIs & Services > OAuth consent screen**.
- Select **External** (or **Internal** for Google Workspace) and click **Create**.
- Enter an App name (e.g., `Google MCP Server`) and your support email.
- In **Scopes**, add:
- `.../auth/documents`
- `.../auth/gmail.compose`
- In **Test users**, add your own Google email address (if external/testing mode).
- Save and continue.
5. Create OAuth 2.0 Credentials:
- Go to **APIs & Services > Credentials**.
- Click **+ CREATE CREDENTIALS** > **OAuth client ID**.
- Application type: **Desktop app**.
- Name: `MCP Desktop Client`.
- Click **Create**.
- Click **DOWNLOAD JSON** and rename the downloaded file to **`credentials.json`**.
- Place `credentials.json` in the root directory of this repository (`c:\MCP-SERVER\credentials.json`).
---
### 3. Install Dependencies
Create a virtual environment (recommended) and install dependencies:
```bash
# Optional: create virtual environment
python -m venv venv
# Windows activate:
venv\Scripts\activate
# Linux/macOS activate:
source venv/bin/activate
# Install requirements
pip install -r requirements.txt
```
---
## ๐ป Running the Server
Start the server using `python` or `uvicorn`:
```bash
python server.py
```
Or:
```bash
uvicorn server:app --host 127.0.0.1 --port 8000 --reload
```
Once running:
- **API Base URL**: `http://127.0.0.1:8000`
- **Interactive Swagger UI Docs**: `http://127.0.0.1:8000/docs`
- **ReDoc Documentation**: `http://127.0.0.1:8000/redoc`
> **Note on First Run**:
> The first time you make a request (or run `python auth.py`), a browser window will automatically open asking you to log into Google and grant permissions. Once granted, a `token.json` file is saved locally so all subsequent requests run without browser interaction.
---
## ๐ก API Usage & Endpoints
### 1. Root & Health Check
#### `GET /`
Returns server status and registry of available MCP tools.
```bash
curl -X GET http://127.0.0.1:8000/
```
Response:
```json
{
"server": "Google Docs & Gmail MCP Server",
"version": "1.0.0",
"status": "online",
"tools": [
{
"name": "append_to_doc",
"endpoint": "/append_to_doc",
"method": "POST",
"description": "Appends text content to an existing Google Document.",
"required_parameters": ["doc_id", "content"]
},
{
"name": "create_email_draft",
"endpoint": "/create_email_draft",
"method": "POST",
"description": "Creates a draft email in Gmail.",
"required_parameters": ["to", "subject", "body"]
}
]
}
```
---
### 2. Append Content to Google Doc
#### `POST /append_to_doc`
**Request Body:**
```json
{
"doc_id": "YOUR_GOOGLE_DOC_ID",
"content": "\n## Summary\nHere is the newly appended text.\n"
}
```
**cURL Example:**
```bash
curl -X POST http://127.0.0.1:8000/append_to_doc \
-H "Content-Type: application/json" \
-d '{
"doc_id": "1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms",
"content": "\n\n### Appended Section\nAutomated analysis report generated."
}'
```
**Terminal Prompt:**
```text
============================================================
โ ๏ธ [ACTION PENDING APPROVAL]: append_to_doc
------------------------------------------------------------
Payload:
{
"doc_id": "1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms",
"content": "\n\n### Appended Section\nAutomated analysis report generated."
}
============================================================
Approve? (y/n): y
โ
Action APPROVED. Executing...
```
**Success Response (HTTP 200):**
```json
{
"status": "success",
"message": "Successfully appended 64 characters to document 'Product Review Summary'.",
"data": {
"status": "success",
"document_id": "1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms",
"document_title": "Product Review Summary",
"characters_appended": 64
}
}
```
**Rejection Response (HTTP 403):**
```json
{
"detail": {
"status": "rejected",
"message": "Action 'append_to_doc' was not approved by the operator in terminal.",
"payload": {
"doc_id": "1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms",
"content": "..."
}
}
}
```
---
### 3. Create Gmail Draft
#### `POST /create_email_draft`
**Request Body:**
```json
{
"to": "recipient@example.com",
"subject": "Weekly Report Draft",
"body": "Hi Team,\n\nPlease review the draft attached.\n\nBest,\nSai"
}
```
**cURL Example:**
```bash
curl -X POST http://127.0.0.1:8000/create_email_draft \
-H "Content-Type: application/json" \
-d '{
"to": "team@example.com",
"subject": "Weekly Review Draft",
"body": "Hello,\n\nPlease find the review draft in your mailbox."
}'
```
**Terminal Prompt:**
```text
============================================================
โ ๏ธ [ACTION PENDING APPROVAL]: create_email_draft
------------------------------------------------------------
Payload:
{
"to": "team@example.com",
"subject": "Weekly Review Draft",
"body": "Hello,\n\nPlease find the review draft in your mailbox."
}
============================================================
Approve? (y/n): y
โ
Action APPROVED. Executing...
```
**Success Response (HTTP 200):**
```json
{
"status": "success",
"message": "Successfully created Gmail draft (ID: r-1234567890) for 'team@example.com'.",
"data": {
"status": "success",
"draft_id": "r-1234567890",
"message_id": "18d1a2b3c4d5e6f7",
"to": "team@example.com",
"subject": "Weekly Review Draft"
}
}
```
---
## ๐งช Testing Suite
You can run automated unit tests that verify all endpoints, authentication handling, Google Docs appending, and Gmail draft generation using mock Google API services:
```bash
pytest -v
```
---
## ๐ Security Best Practices
- `credentials.json` contains your client secret and `token.json` contains refresh tokens granting access to your Docs and Gmail.
- Both files are ignored in `.gitignore` โ **never commit them to public version control**.
- The interactive terminal approval mechanism acts as a guardrail against unauthorized or unintended agent actions.
---
## โ๏ธ Cloud Deployment (Railway)
To deploy this MCP server to **Railway** as a 24/7 cloud API service:
- Complete step-by-step instructions, environment variable setup (`GOOGLE_TOKEN_JSON`, `GOOGLE_CREDENTIALS_JSON`, `REQUIRE_TERMINAL_APPROVAL=false`), and security options are detailed in **[`deployment.md`](deployment.md)**.