mcp-gsuite
by khokan
README.md
# mcp-gsuite
[](https://mcpize.com)
A **Model Context Protocol (MCP) server** for interacting with **Google Workspace** ā Gmail & Google Calendar ā via a streamable HTTP transport. Built with TypeScript, Express, and the official Google APIs Node.js client.
---
## Features
- š§ **Gmail** ā list, search, send, and label emails
- š
**Google Calendar** ā list, create, update, and delete events
- š **OAuth 2.0** ā offline access via refresh tokens (no re-auth needed)
- ā” **Stateful sessions** ā each MCP client gets its own isolated session
- š³ **Docker-ready** ā includes a production-grade Dockerfile
- āļø **Cloud Run compatible** ā graceful SIGTERM/SIGINT shutdown handling
---
## Quick Start
```bash
npm install
npm run dev # Start with hot reload (tsx watch)
```
**Local development:**
- **MCP endpoint:** `http://localhost:8080/mcp`
- **Health check:** `http://localhost:8080/health`
**Remote (MCPize hosted):**
- **MCP endpoint:** `https://mcp-gsuite.mcpize.run/mcp`
---
## Prerequisites
1. A **Google Cloud project** with the following APIs enabled:
- Gmail API
- Google Calendar API
2. **OAuth 2.0 Web Application credentials** ā download as `credentials.json` from Google Cloud Console
3. A **refresh token** for offline access (see below)
### credentials.json format
```json
{
"web": {
"client_id": "YOUR_CLIENT_ID.apps.googleusercontent.com",
"client_secret": "YOUR_CLIENT_SECRET",
"redirect_uris": [
"https://your-deployed-url/mcp",
"http://localhost:4100/mcp"
],
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://oauth2.googleapis.com/token"
}
}
```
### Getting a Refresh Token
```bash
npm run generate # Automated OAuth flow (recommended)
# or
node get-refresh-token.js
```
The script will open a browser for Google sign-in and save the token to `.env` automatically.
---
## Environment Variables
Copy `.env.example` to `.env` and fill in:
```bash
cp .env.example .env
```
| Variable | Description | Required |
|---|---|---|
| `GOOGLE_CLIENT_ID` | OAuth client ID from Google Cloud Console | ā
|
| `GOOGLE_CLIENT_SECRET` | OAuth client secret | ā
|
| `GOOGLE_REFRESH_TOKEN` | Refresh token for offline access | ā
|
| `PORT` | Server port (default: `8080`) | ā |
| `NODE_ENV` | Set to `production` to disable dev logging | ā |
> **Note:** The server will **throw an error on startup** if any of the three required credentials are missing.
---
## Development
```bash
npm install # Install dependencies
npm run dev # Development mode with hot reload (tsx watch)
npm run build # Compile TypeScript to dist/
npm start # Run compiled server (node dist/index.js)
npm test # Run unit tests (vitest)
npm run test:smoke # Run smoke/connectivity test
```
---
## Project Structure
```
āāā src/
ā āāā index.ts # MCP server ā all tool handlers & Express setup
āāā tests/
ā āāā tools.test.ts # Vitest unit tests
āāā scripts/
ā āāā list-events.mjs # Standalone calendar event listing script
ā āāā smoke-test.js # Basic connectivity smoke test
āāā get-refresh-token.js # Automated OAuth flow helper
āāā credentials.json # Google OAuth client credentials (not committed)
āāā token.json # Cached OAuth tokens (auto-generated, not committed)
āāā package.json # Dependencies and npm scripts
āāā tsconfig.json # TypeScript compiler configuration
āāā mcpize.yaml # MCPize deployment manifest
āāā Dockerfile # Container build instructions
āāā .env # Your local secrets (not committed)
āāā .env.example # Environment variables template
```
---
## MCP Tools
### š§ Gmail
| Tool | Description | Key Parameters |
|---|---|---|
| `list_emails` | List recent emails from Gmail inbox | `maxResults` (1ā500, default 10), `query` (Gmail filter) |
| `search_emails` | Search emails with Gmail query syntax | `query` (required), `maxResults` (1ā500, default 10) |
| `send_email` | Send an email (plain text + HTML) | `to`, `subject`, `body`, `cc?`, `bcc?` |
| `modify_email` | Add or remove Gmail labels on a message | `id`, `addLabels[]`, `removeLabels[]` |
**Gmail search query examples:**
```
from:someone@example.com
subject:invoice
is:unread after:2024/01/01
```
### š
Google Calendar
| Tool | Description | Key Parameters |
|---|---|---|
| `list_events` | List upcoming calendar events | `maxResults` (1ā250, default 10), `timeMin?`, `timeMax?` |
| `create_event` | Create a new calendar event | `summary`, `start`, `end`, `location?`, `description?`, `attendees[]?` |
| `update_event` | Update an existing calendar event (partial patch) | `eventId`, any of: `summary`, `location`, `description`, `start`, `end`, `attendees[]` |
| `delete_event` | Delete a calendar event | `eventId` |
> All datetime values must be valid **ISO 8601** strings (e.g., `2024-12-25T10:00:00Z`).
---
## Architecture
The server uses **stateful Streamable HTTP sessions** from the MCP SDK:
- Each new MCP `initialize` request creates a fresh server + transport instance
- Sessions are tracked in memory by `mcp-session-id` header
- A single authenticated `OAuth2` client is shared across Gmail and Calendar API calls within a session
- Input validation is handled via **Zod schemas** on all tool inputs
```
Client ā POST /mcp (initialize) ā creates session
Client ā POST /mcp (tool call, mcp-session-id: <id>) ā reuses session
```
---
## Testing
```bash
npm test # Run vitest unit tests
npx @anthropic-ai/mcp-inspector # Interactive MCP tool testing UI
npm run test:smoke # Smoke test against running server
```
Connect MCP Inspector to `http://localhost:8080/mcp` to test tools interactively.
---
## Deployment
### MCPize (recommended)
```bash
mcpize deploy
```
Configured via [`mcpize.yaml`](./mcpize.yaml):
- **Runtime:** TypeScript
- **Build:** `npm ci && npm run build`
- **Start:** `node dist/index.js` (HTTP transport on `$PORT`)
### Docker
```bash
docker build -t mcp-gsuite .
docker run -p 8080:8080 \
-e GOOGLE_CLIENT_ID=... \
-e GOOGLE_CLIENT_SECRET=... \
-e GOOGLE_REFRESH_TOKEN=... \
mcp-gsuite
```
### Google Cloud Run
The server handles `SIGTERM` gracefully for zero-downtime Cloud Run deploys.
---
## Tech Stack
| Package | Version | Purpose |
|---|---|---|
| `@modelcontextprotocol/sdk` | ^1.23.0 | MCP server + Streamable HTTP transport |
| `googleapis` | ^134.0.0 | Gmail & Calendar API client |
| `express` | ^5.1.0 | HTTP server framework |
| `zod` | ^4.0.0 | Runtime input validation |
| `dotenv` | ^16.4.5 | Environment variable loading |
| `chalk` | ^5.4.1 | Colored terminal output |
| `tsx` | ^4.19.4 | TypeScript dev runner (hot reload) |
**Node.js requirement:** `>=20.0.0`
---
## License
MIT
This server cannot be deployed
Maintenance
ActivityInactive
ResponsivenessNo issues