google-workspace-mcp-server
by princegrg17
README.md
# Google Workspace MCP Server
A generic, agent-agnostic **Model Context Protocol (MCP) server** that exposes Gmail and Google Docs capabilities as tools. Any MCP-compatible client (Antigravity, Claude Desktop, custom agents) can connect and use these tools without code changes.
## Available Tools
| Tool | Description |
|---|---|
| `gmail_send_email` | Send an email via Gmail on behalf of the authenticated user |
| `gmail_create_draft` | Create a draft email in Gmail without sending |
| `gdocs_append_content` | Append text content to the end of a Google Doc |
## Prerequisites
- **Node.js** 18 or later
- A **Google Cloud** project with billing enabled (or free tier)
## Google Cloud Setup
### 1. Create a Google Cloud Project
1. Go to [Google Cloud Console](https://console.cloud.google.com/).
2. Create a new project (or select an existing one).
### 2. Enable APIs
Enable the following APIs for your project:
- **Gmail API**: [Enable here](https://console.cloud.google.com/apis/library/gmail.googleapis.com)
- **Google Docs API**: [Enable here](https://console.cloud.google.com/apis/library/docs.googleapis.com)
### 3. Create OAuth 2.0 Credentials
1. Go to **APIs & Services → Credentials**.
2. Click **Create Credentials → OAuth client ID**.
3. Select **Desktop app** as the application type.
4. Name it (e.g., "MCP Server") and click **Create**.
5. Download or copy the **Client ID** and **Client Secret**.
### 4. Configure the OAuth Consent Screen
1. Go to **APIs & Services → OAuth consent screen**.
2. Select **External** user type (or Internal if using Workspace).
3. Fill in the required app info and add the following scopes:
- `https://www.googleapis.com/auth/gmail.send`
- `https://www.googleapis.com/auth/gmail.compose`
- `https://www.googleapis.com/auth/documents`
4. Add your Google account as a **test user** (required for external apps in testing).
## Installation
```bash
# Clone or navigate to the project directory
cd mcp-server
# Install dependencies
npm install
# Copy the environment template
cp .env.example .env
```
Edit `.env` and fill in your Google credentials:
```env
GOOGLE_CLIENT_ID=your-client-id.apps.googleusercontent.com
GOOGLE_CLIENT_SECRET=your-client-secret
GOOGLE_REDIRECT_URI=urn:ietf:wg:oauth:2.0:oob
GOOGLE_TOKEN_PATH=./token.json
```
## Authorization
Run the one-time authorization flow to grant the server access to your Google account:
```bash
npm run authorize
```
This will:
1. Display a URL — open it in your browser.
2. Sign in with your Google account and grant access.
3. Paste the authorization code back into the terminal.
4. Save the OAuth tokens to `token.json`.
> **Note:** You only need to do this once. Tokens refresh automatically after that.
## Running the Server
### Development (with hot reload)
```bash
npm run dev
```
### Production
```bash
npm run build
npm start
```
## Connecting to MCP Clients
### Antigravity
Add to your Antigravity MCP settings:
```json
{
"mcpServers": {
"google-workspace": {
"command": "node",
"args": ["C:/path/to/mcp-server/dist/index.js"]
}
}
}
```
### Claude Desktop
Add to your `claude_desktop_config.json`:
```json
{
"mcpServers": {
"google-workspace": {
"command": "node",
"args": ["/absolute/path/to/mcp-server/dist/index.js"]
}
}
}
```
### MCP Inspector (Testing)
Use the MCP Inspector to test your tools interactively:
```bash
npx @modelcontextprotocol/inspector node dist/index.js
```
## Tool Schemas
### gmail_send_email
```json
{
"to": "recipient@example.com",
"subject": "Hello from MCP",
"body": "This email was sent by an AI agent via the MCP server.",
"cc": "cc@example.com",
"bcc": ["bcc1@example.com", "bcc2@example.com"],
"body_html": "<h1>Hello</h1><p>HTML email body</p>"
}
```
### gmail_create_draft
Same schema as `gmail_send_email`. Creates a draft without sending.
### gdocs_append_content
```json
{
"document_id": "1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgVf2oVzk",
"content": "This text was appended by an AI agent.",
"add_newline": true
}
```
## Troubleshooting
| Problem | Solution |
|---|---|
| `Missing GOOGLE_CLIENT_ID` | Copy `.env.example` to `.env` and fill in your credentials |
| `No OAuth tokens found` | Run `npm run authorize` to complete the consent flow |
| `Token refresh failed` | Delete `token.json` and run `npm run authorize` again |
| `403 Forbidden` | Ensure the Gmail and Docs APIs are enabled in your Google Cloud project |
| `Invalid document ID` | The document ID is the long string in the URL: `docs.google.com/document/d/{ID}/edit` |
| `Access denied` | Make sure your account is added as a test user in the OAuth consent screen |
| `401 Unauthorized` (cloud) | Set `Authorization: Bearer <API_KEY>` header when connecting to the remote server |
| `GOOGLE_TOKENS_JSON decode error` | Re-run `npm run export-token` locally and update the env var |
## Deploy to Railway
### Prerequisites
- The MCP server running locally with a valid `token.json` (complete the [Authorization](#authorization) steps first)
- A [Railway](https://railway.app) account
- A GitHub repository with this code pushed
### Step 1: Export Your Token
```bash
npm run export-token
```
This outputs a Base64-encoded string of your `token.json`. Copy it — you'll need it in Step 3.
### Step 2: Create Railway Service
1. Go to [Railway Dashboard](https://railway.app/dashboard).
2. Click **New Project → Deploy from GitHub Repo**.
3. Select your repository.
4. Railway will auto-detect the `Dockerfile` and begin building.
### Step 3: Set Environment Variables
In the Railway service dashboard, go to **Variables** and add:
| Variable | Value |
|---|---|
| `TRANSPORT` | `http` |
| `GOOGLE_CLIENT_ID` | Your Google OAuth client ID |
| `GOOGLE_CLIENT_SECRET` | Your Google OAuth client secret |
| `GOOGLE_TOKENS_JSON` | The Base64 string from Step 1 |
| `API_KEY` | A secret key of your choice (for securing the endpoint) |
> **Note:** `PORT` is injected automatically by Railway. Do not set it manually.
### Step 4: Deploy
Railway will automatically build and deploy. Once live, you'll get a public URL like:
```
https://your-app-name.up.railway.app
```
### Step 5: Verify
```bash
# Health check
curl https://your-app-name.up.railway.app/health
# Test MCP endpoint (replace YOUR_API_KEY)
curl -X POST https://your-app-name.up.railway.app/mcp \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_API_KEY" \
-d '{"jsonrpc":"2.0","method":"initialize","params":{"capabilities":{}},"id":1}'
```
### Step 6: Connect Remote MCP Client
Configure your MCP client to connect to the deployed server. Example for clients that support Streamable HTTP:
```json
{
"mcpServers": {
"google-workspace-remote": {
"url": "https://your-app-name.up.railway.app/mcp",
"headers": {
"Authorization": "Bearer YOUR_API_KEY"
}
}
}
}
```
## Project Structure
```
├── src/
│ ├── index.ts # Server entry point (stdio + HTTP dual transport)
│ ├── auth/
│ │ └── google-auth.ts # OAuth2 authentication (file + env var dual mode)
│ ├── services/
│ │ ├── gmail.service.ts # Gmail API logic
│ │ └── gdocs.service.ts # Google Docs API logic
│ ├── tools/
│ │ ├── gmail-send-email.ts # gmail_send_email tool
│ │ ├── gmail-create-draft.ts # gmail_create_draft tool
│ │ └── gdocs-append.ts # gdocs_append_content tool
│ └── utils/
│ └── mime.ts # MIME message builder
├── scripts/
│ ├── authorize.ts # OAuth consent flow script
│ └── export-token.ts # Token export for cloud deployment
├── Dockerfile # Multi-stage Docker build
├── railway.toml # Railway deployment config
├── .env.example # Environment variable template
├── package.json
├── tsconfig.json
└── README.md
```
## License
MIT
This server cannot be deployed
Maintenance
ActivityInactive
ResponsivenessNo issues