Skip to main content
Glama
dsingh80

Google Docs MCP Proxy

by dsingh80
README.md
# Google Docs MCP Proxy

A local stdio MCP server that handles Google OAuth2 locally and proxies authenticated requests to the **Google Docs** and **Google Drive** REST APIs.

This solves the problem where Cursor cannot complete OAuth for Google's hosted Workspace MCP servers (Google does not support the `cursor://` redirect protocol).

## Architecture

```
Cursor Agent ──stdio JSON-RPC──► Local MCP Server ──Bearer──► docs.googleapis.com
                                        │                  └──► drive.googleapis.com
                                        └──► OAuth2 Token Manager ──► Google OAuth
```

## Prerequisites

1. A Google Cloud project with:
   - **Google Docs API** enabled
   - **Google Drive API** enabled
   - OAuth consent screen configured with scopes:
     - `https://www.googleapis.com/auth/documents`
     - `https://www.googleapis.com/auth/drive`
   - OAuth 2.0 client of type **Desktop app** (not Web application)
     — Desktop app clients allow `http://127.0.0.1` redirects without pre-registration

2. Node.js 18+

## Setup

### 1. Install dependencies

```bash
npm install
```

### 2. Configure environment

```bash
cp .env.example .env
```

Edit `.env` and fill in your OAuth client credentials from Google Cloud Console:

```env
GOOGLE_CLIENT_ID=your-client-id.apps.googleusercontent.com
GOOGLE_CLIENT_SECRET=your-client-secret
```

### 3. Authorize (one-time)

```bash
npm run auth
```

This opens your browser to Google's consent screen, completes the OAuth2 flow, and saves tokens to `token.json` (gitignored). You only need to do this once — tokens refresh automatically.

**Headless alternative:** Set `GOOGLE_REFRESH_TOKEN=<your-refresh-token>` in `.env` to skip the interactive flow entirely.

### 4. Add to Cursor's mcp.json

Add the following entry to `~/.cursor/mcp.json` (under `mcpServers`):

```json
"google-docs": {
  "command": "node",
  "args": [
    "D:\\Documents\\_Projects\\google-docs-mcp\\node_modules\\tsx\\dist\\cli.mjs",
    "D:\\Documents\\_Projects\\google-docs-mcp\\src\\index.ts"
  ]
}
```

Restart Cursor after saving.

## MCP Tools

### `google_docs_request`

Make any request to the [Google Docs REST API](https://developers.google.com/docs/api/reference/rest).

| Parameter | Type | Description |
|-----------|------|-------------|
| `path` | string | Path after `/v1/`, e.g. `documents/{id}:batchUpdate` |
| `method` | GET \| POST \| PATCH \| PUT \| DELETE | HTTP method |
| `body` | object (optional) | JSON request body |
| `query` | object (optional) | Query string params (string values) |

**Examples:**

Create a document:
```json
{ "path": "documents", "method": "POST", "body": { "title": "My New Doc" } }
```

Read a document:
```json
{ "path": "documents/DOC_ID", "method": "GET" }
```

Insert text via batchUpdate:
```json
{
  "path": "documents/DOC_ID:batchUpdate",
  "method": "POST",
  "body": {
    "requests": [
      { "insertText": { "text": "Hello world\n", "location": { "index": 1 } } }
    ]
  }
}
```

### `google_drive_request`

Make any request to the [Google Drive REST API v3](https://developers.google.com/drive/api/reference/rest/v3).

Same parameters; base URL is `https://www.googleapis.com/drive/v3/`.

**Examples:**

List files:
```json
{ "path": "files", "method": "GET", "query": { "pageSize": "10" } }
```

Search for docs:
```json
{
  "path": "files",
  "method": "GET",
  "query": { "q": "mimeType='application/vnd.google-apps.document'", "pageSize": "5" }
}
```

## Development

```bash
npm run dev    # tsx --watch (hot reload)
npm start      # run once
npm run auth   # re-authorize (if tokens are revoked)
```

## Security notes

- `.env` and `token.json` are gitignored — never commit them
- OAuth credentials live in the project `.env`, not in global `mcp.json`
- Token refresh happens automatically via native fetch; no manual intervention needed after initial auth

Maintenance

ActivityStale
ResponsivenessNo issues