Skip to main content
Glama
bsaiprasad13-main

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)**.