# @ibarcarty/mcp-server-google-drive A Model Context Protocol (MCP) server for Google Drive, Google Docs, Google Sheets, Google Slides, Google Calendar and Gmail drafts with **full read/write operations** and **rich markdown formatting**. Search, read, create, edit, delete, move, copy files, edit documents with native formatting, manage spreadsheets, modify presentations, manage calendar events, leave Gmail drafts for human review, and control permissions — including shared drives. Built with official Google APIs (`googleapis`) and the official MCP SDK (`@modelcontextprotocol/sdk`). ## Features - **33 tools** for complete Google Drive, Docs, Sheets, Slides, Calendar and Gmail-draft management - **Google Calendar**: list events (recurring events expanded), create timed or all-day events with recurrence (RRULE) and reminders, update, and delete. All-day end dates are inclusive (the server handles the API's exclusive convention) - **Gmail drafts — never send**: `gmail_create_draft` leaves a draft in the user's Drafts folder for human review. By design this server ships **no send capability**: the human always presses Send in Gmail - **Safe reads for any size**: regular files are read by byte ranges (`offset`/`maxBytes`) — a 90MB file no longer kills the transport, you page through it - **Office files readable**: `.docx`/`.xlsx`/`.pptx` (and legacy/OpenDocument variants) are converted to text on read via a temporary Google Workspace copy — no more lossy binary dumps - **Shared-drive-aware deletes**: when permanent deletion is not permitted (non-organizer in a shared drive), the file is moved to trash with a clear explanation instead of a misleading `File not found` - **File metadata by ID** (`drive_get_file_info`): name, type, size, timestamps, parent folder resolved to its name, shared drive, owners, capabilities - **Rich markdown → Google Docs** (`docs_write_markdown`): headings, bold, italic, strikethrough, inline code, code blocks, tables, lists, links, blockquotes — all as native Google Docs formatting - **Document theming** (`docs_apply_theme`): apply a consistent visual theme (typography, colors, spacing, margins) to an entire document. Built-in `corporate` and `minimal` themes. Custom themes loadable from a JSON file via env var - **Corporate document templates** (`docs_apply_corporate_template`): initialize a document with title, metadata, change log, classification badge, and footer — useful for standard corporate deliverables - **Google Docs editing**: read, append, insert, find & replace, and write formatted markdown - **Google Sheets editing**: read, write, append rows, and clear cell ranges - **Google Slides editing**: read presentations, add slides, insert text, and find & replace - **File management**: create, read, update, delete, move, copy files and folders - **Permissions**: share files, list access, revoke permissions - **Shared drives** supported by default in all operations - **Google Workspace export**: Docs → Markdown, Sheets → CSV, Slides → text - **Two transport modes**: local (stdio) and remote (Streamable HTTP for Cloud Run) - **OAuth2** with automatic token refresh - **TypeScript** — fully typed, strict mode ## Quick Start ### 1. Set up OAuth credentials Follow the [OAuth Setup Guide](docs/oauth-setup.md) to create credentials in Google Cloud Console. **Important:** You must enable these APIs in your GCP project: - Google Drive API - Google Docs API - Google Sheets API - Google Slides API - Google Calendar API (for the `calendar_*` tools) ### 2. Install **From npm:** ```bash npx @ibarcarty/mcp-server-google-drive auth ``` **From source:** ```bash git clone https://github.com/ibarcarty/mcp-server-google-drive.git cd mcp-server-google-drive npm install --ignore-scripts npm run build node dist/index.js auth ``` This opens your browser to authorize with your Google account. Tokens are saved locally. ### 3. Configure Claude Code / Claude Desktop **From npm:** ```json { "mcpServers": { "google-drive": { "command": "npx", "args": ["-y", "@ibarcarty/mcp-server-google-drive"], "env": { "GDRIVE_MCP_OAUTH_PATH": "/path/to/your/oauth-credentials.json" } } } } ``` **From source:** ```json { "mcpServers": { "google-drive": { "command": "node", "args": ["/path/to/mcp-server-google-drive/dist/index.js"], "env": { "GDRIVE_MCP_OAUTH_PATH": "/path/to/your/oauth-credentials.json" } } } } ``` See [Local Setup Guide](docs/setup-local.md) for detailed instructions. ## Tools ### Drive — File Operations | Tool | Description | |------|-------------| | `drive_list_files` | List files/folders with filtering, pagination, and sorting | | `drive_search` | Search by name or content (full-text search) | | `drive_read_file` | Read file content by byte ranges. Auto-exports Workspace files, converts Office files to text | | `drive_get_file_info` | Metadata for an ID: name, size, parent folder (resolved to its name), shared drive, capabilities | | `drive_create_file` | Create a new file with optional content | | `drive_create_folder` | Create a new folder | | `drive_update_file` | Update file content or rename | | `drive_delete_file` | Delete a file or folder (falls back to trash in shared drives when permanent delete is not permitted) | | `drive_move_file` | Move to a different folder | | `drive_copy_file` | Copy a file, optionally to a different folder | ### Drive — Permissions | Tool | Description | |------|-------------| | `drive_share` | Share a file with a user (reader/writer/commenter) | | `drive_list_permissions` | List who has access to a file | | `drive_remove_permission` | Revoke access from a user | ### Google Docs — Document Editing | Tool | Description | |------|-------------| | `docs_read` | Read document content with structure (headings, indexes) | | `docs_append_text` | Append plain text at the end of a document | | `docs_insert_text` | Insert plain text at a specific position (by index) | | `docs_replace_text` | Find and replace text throughout a document | | `docs_write_markdown` | Write GitHub Flavored Markdown with native rich formatting (headings, bold, italic, strikethrough, inline code, code blocks, tables, lists, links, blockquotes) | | `docs_apply_theme` | Apply a predefined visual theme (typography, colors, spacing, margins) to an entire document. Built-in: `corporate`, `minimal`. Custom themes loadable from JSON | | `docs_apply_corporate_template` | Initialize a document with title, metadata, change log, classification badge, and footer | #### Markdown-to-Docs example ```javascript // Write rich markdown to an existing Google Doc await mcp.callTool("docs_write_markdown", { documentId: "1abc...xyz", markdown: ` # Project Report ## Summary This project delivers **three key features**: - Feature A with *italic emphasis* - Feature B using \`inline code\` - Feature C — [see docs](https://example.com) ## Timeline | Phase | Start | End | |-------|-------|-----| | Design | Jan | Feb | | Build | Mar | May | `, mode: "append", // or "replace_all" }); // Apply the built-in corporate theme await mcp.callTool("docs_apply_theme", { documentId: "1abc...xyz", theme: "corporate", }); ``` #### Custom themes Built-in themes (`corporate`, `minimal`) cover most cases. For custom branding, point `GDRIVE_MCP_CUSTOM_THEMES_PATH` to a JSON file: ```json { "my-brand": { "name": "my-brand", "fontFamily": "Arial", "lineSpacing": 115, "margins": { "top": 71, "bottom": 71, "left": 71, "right": 71 }, "styles": { "TITLE": { "fontSize": 26, "bold": true, "color": { "red": 0.0, "green": 0.32, "blue": 0.53 }, "spaceAbove": 0, "spaceBelow": 12 }, "SUBTITLE": { "fontSize": 16, "color": { "red": 0.18, "green": 0.18, "blue": 0.18 }, "spaceAbove": 0, "spaceBelow": 12 }, "HEADING_1": { "fontSize": 20, "bold": true, "color": { "red": 0.0, "green": 0.32, "blue": 0.53 }, "spaceAbove": 16, "spaceBelow": 6 }, "HEADING_2": { "fontSize": 16, "bold": true, "color": { "red": 0.30, "green": 0.51, "blue": 0.74 }, "spaceAbove": 12, "spaceBelow": 4 }, "HEADING_3": { "fontSize": 13, "bold": true, "color": { "red": 0.30, "green": 0.51, "blue": 0.74 }, "spaceAbove": 10, "spaceBelow": 4 }, "HEADING_4": { "fontSize": 12, "bold": true, "color": { "red": 0.18, "green": 0.18, "blue": 0.18 }, "spaceAbove": 8, "spaceBelow": 2 }, "HEADING_5": { "fontSize": 11, "bold": true, "color": { "red": 0.18, "green": 0.18, "blue": 0.18 }, "spaceAbove": 6, "spaceBelow": 2 }, "HEADING_6": { "fontSize": 10, "bold": true, "color": { "red": 0.18, "green": 0.18, "blue": 0.18 }, "spaceAbove": 6, "spaceBelow": 2 }, "NORMAL_TEXT": { "fontSize": 11, "color": { "red": 0.18, "green": 0.18, "blue": 0.18 }, "spaceAbove": 0, "spaceBelow": 4 } } } } ``` Then apply it by name: `{ theme: "my-brand" }`. The markdown is parsed with `remark` + `remark-gfm` (CommonMark + GFM extensions) and converted to native Google Docs `batchUpdate` requests (`insertText`, `updateTextStyle`, `updateParagraphStyle`, `insertTable`, `createParagraphBullets`, `updateTableCellStyle`). No markdown characters remain in the document — it becomes native Google Docs formatting. ### Google Sheets — Spreadsheet Editing | Tool | Description | |------|-------------| | `sheets_read_range` | Read cell values from a range (A1 notation) | | `sheets_write_range` | Write values to a range of cells | | `sheets_append_rows` | Append rows after the last row with data | | `sheets_clear_range` | Clear values in a range (formatting preserved) | ### Google Slides — Presentation Editing | Tool | Description | |------|-------------| | `slides_read` | Read all slides with text content and element IDs | | `slides_add_slide` | Add a new slide to the presentation | | `slides_add_text` | Insert text into a specific shape/placeholder | | `slides_replace_text` | Find and replace text across all slides | ### Google Calendar — Event Management | Tool | Description | |------|-------------| | `calendar_list_events` | List events in a time window (recurring events expanded into instances, ordered by start time). Returns the event IDs used by update/delete | | `calendar_create_event` | Create a timed or all-day event, with optional recurrence (RRULE), reminders (popup/email), location and description. Timed events default to Europe/Madrid and 1h duration; all-day end dates are inclusive | | `calendar_update_event` | Patch fields of an existing event (only the provided fields change) | | `calendar_delete_event` | Delete an event by ID (a recurring event's parent removes all instances) | ### Gmail — Drafts only (red line: no sending) | Tool | Description | |------|-------------| | `gmail_create_draft` | Create a plain-text DRAFT (to/cc/bcc, UTF-8 safe subject and body) in the authenticated user's Drafts folder. The server **never sends email** — there is deliberately no send tool; the user reviews the draft in Gmail and presses Send themselves | ## Configuration All configuration is via environment variables. All are optional with sensible defaults. | Variable | Default | Description | |----------|---------|-------------| | `GDRIVE_MCP_OAUTH_PATH` | `~/.config/mcp-server-google-drive/oauth-credentials.json` | OAuth client credentials file | | `GDRIVE_MCP_TOKEN_PATH` | `~/.config/mcp-server-google-drive/tokens.json` | Saved tokens file | | `GDRIVE_MCP_SCOPES` | `https://www.googleapis.com/auth/drive,https://www.googleapis.com/auth/calendar,https://www.googleapis.com/auth/gmail.compose` | OAuth scopes (comma-separated) | | `GDRIVE_MCP_TRANSPORT` | `stdio` | Transport: `stdio` or `http` | | `GDRIVE_MCP_PORT` | `8080` | HTTP port (for `http` transport) | | `GDRIVE_MCP_HOST` | `0.0.0.0` | HTTP bind address | | `GDRIVE_MCP_CUSTOM_THEMES_PATH` | *(unset)* | Optional path to a JSON file with custom theme specifications | On Windows, the default config directory is `%APPDATA%/mcp-server-google-drive/`. ## Deployment ### Local (recommended for personal use) Uses stdio transport. See [Local Setup Guide](docs/setup-local.md). ### Google Cloud Run (for teams) Uses Streamable HTTP transport. See [Cloud Run Deployment Guide](docs/setup-cloudrun.md). ## Development ```bash git clone https://github.com/ibarcarty/mcp-server-google-drive.git cd mcp-server-google-drive npm install --ignore-scripts npm run build npm test # unit tests (node:test via tsx, API fully mocked) npm run smoke # live smoke test against the real Drive API (requires credentials; creates and removes its own fixtures) ``` ## OAuth Scopes This server uses `https://www.googleapis.com/auth/drive` (full Drive access — also covers Google Docs, Google Sheets, and Google Slides) plus `https://www.googleapis.com/auth/calendar` (Google Calendar) and `https://www.googleapis.com/auth/gmail.compose` (Gmail drafts) by default. **About `gmail.compose`:** Google offers no drafts-only scope — `gmail.compose` technically permits sending. This server's guarantee is structural: it ships **no send tool** (nothing calls `drafts.send` or `messages.send`, enforced by contract tests). If you don't want the Gmail tools at all, set `GDRIVE_MCP_SCOPES` without `gmail.compose`. **Upgrading from ≤1.3.x:** tokens saved before an upgrade lack the newer scopes (calendar since v1.3.0, gmail.compose since v1.4.0). Re-run the auth flow once (`node dist/index.js auth` or `npx @ibarcarty/mcp-server-google-drive auth`) to grant them; the affected tools return an actionable error until then. If you only need access to files created by this app, you can use the more restrictive `drive.file` scope: ```bash GDRIVE_MCP_SCOPES=https://www.googleapis.com/auth/drive.file npx @ibarcarty/mcp-server-google-drive auth ``` **Note:** The `drive` scope requires Google verification for apps with 100+ users. For personal use or small teams (< 100 users), testing mode works without verification. ## Limitations - `docs_write_markdown` covers CommonMark + GFM (headings, emphasis, lists, links, code blocks, blockquotes, tables, strikethrough). Images, footnotes, and task lists with interactive checkboxes are rendered as plain text or placeholders. - Google Slides editing supports text operations and adding slides. Complex layout operations (positioning shapes, animations) require using the raw Slides API. - Export of Workspace files has a 10MB limit (Google API limitation). - Binary file uploads are limited to text content passed as strings. For large binary files, use Google Drive directly. - Binary files (PDF, images, archives…) are reported with their metadata but not returned inline — decoding them as text would be lossy. Office files are the exception: they are converted to text on read. - `drive_read_file` returns at most 2MB per call (default window 200KB). Page through larger files with `offset`. - Reading a byte range of a UTF-8 text file may split a multibyte character at the window boundaries. ## Changelog ### v1.4.0 - **NEW** Gmail drafts (1 tool, test-first with 7 contract tests): `gmail_create_draft` builds an RFC 2822 message (RFC 2047 UTF-8 subject encoding, base64 body, CRLF header-injection rejected) and creates a DRAFT via `users.drafts.create`. - **Red line by design: the server never sends email.** No send tool exists; the contract tests assert zero calls to `drafts.send`/`messages.send` in every scenario. The user reviews drafts in Gmail and sends manually. - Default OAuth scopes now include `https://www.googleapis.com/auth/gmail.compose`. Existing tokens keep working for everything else; re-run the auth flow once to enable the draft tool. Requires the Gmail API enabled in the GCP project. ### v1.3.0 - **NEW** Google Calendar support (4 tools, test-first with 13 contract tests): `calendar_list_events` (recurring events expanded via `singleEvents`, ordered by start time), `calendar_create_event` (timed or all-day; RRULE recurrence; popup/email reminders; Europe/Madrid default timezone; 1h default duration; inclusive all-day end dates converted to the API's exclusive convention), `calendar_update_event` (patch semantics), `calendar_delete_event`. - Default OAuth scopes now include `https://www.googleapis.com/auth/calendar`. Existing tokens keep working for Drive/Docs/Sheets/Slides; re-run the auth flow once to enable the calendar tools. A 403 for a missing scope returns an actionable message instead of a raw API error. - Requires the Google Calendar API to be enabled in the GCP project. ### v1.2.0 Four defects found using the server against a large real-world Drive, all fixed test-first (17 unit tests + an 11-case live smoke suite, `test/`): - **FIX** `drive_read_file` no longer downloads files whole: reads go through byte ranges (`Range` header) with a 200KB default window and new `offset`/`maxBytes` parameters. Previously a 90MB file crashed the stdio transport (`Connection closed`). Truncated responses say exactly how to continue. - **FIX** `drive_read_file` converts Office files (`.docx`, `.xlsx`, `.pptx`, legacy and OpenDocument variants) to text via a temporary Google Workspace copy (always cleaned up, even on failure). Previously the raw bytes were decoded as UTF-8, producing irreversible `U+FFFD` mojibake. Binary files (PDF, images, archives) are now reported instead of dumped; binary *export formats* of Workspace files get a clear message pointing to the text formats. - **FIX** `drive_delete_file` handles shared drives correctly: the Drive API answers an ambiguous **404 "File not found"** (not 403) when a non-organizer attempts a permanent delete in a shared drive — verified live, with and without `supportsAllDrives`. The tool now checks `capabilities` first and falls back to moving the item to the trash with a transparent message; a genuine 404 explains both possible causes. - **NEW** `drive_get_file_info`: metadata for a file/folder ID — name, type, size, timestamps, parent folder resolved to its name, shared drive name, owners, capabilities, links. Previously there was no way to identify an item from its ID without listing its contents. - **FIX** The MCP server now announces its real version (was hardcoded to an older one). ### v1.1.1 - **Maintenance**: harden `build` script to clean `dist/` before compiling (prevents stale artifacts from previous compilations being published). Users should upgrade from v1.1.0 to this version. - No functional changes vs v1.1.0. ### v1.1.0 - **NEW** `docs_write_markdown`: convert GitHub Flavored Markdown to native Google Docs formatting (headings, bold, italic, strikethrough, inline code, code blocks, tables, lists, links, blockquotes). - **NEW** `docs_apply_theme`: apply a consistent visual theme across a document. Built-in themes: `corporate` (Arial, corporate blue), `minimal` (Inter, neutral). Custom themes can be loaded from a JSON file via `GDRIVE_MCP_CUSTOM_THEMES_PATH`. - **NEW** `docs_apply_corporate_template`: initialize a document with a standard corporate structure (title, metadata, change log, classification badge, footer). - Parser powered by `unified` + `remark-parse` + `remark-gfm` (industry standard). - Zero extra token cost vs raw text — model sends markdown, server handles the conversion. ### v1.0.1 - Initial public release with 24 tools across Drive, Docs, Sheets, Slides. ## License MIT