Back

Google Workspace

Gmail, Calendar, Contacts, Drive, Sheets, Docs, Slides

64 capabilitiesView Source ↗

Google Workspace MCP Server

A Model Context Protocol server that gives Claude access to Google Workspace — Gmail, Calendar, Drive, Contacts, Sheets, Docs, Slides, Tasks, and 100+ APIs via the gws CLI.

This server powers the Google Workspace connector of DataToRAG, a hosted MCP gateway with per-user OAuth, multi-account support, and Atlassian tools alongside these — add https://datatorag.com/mcp to your MCP client and skip the setup below. Or run this server yourself, standalone or as a Claude Desktop extension.

Tools

Service Tools Operations
Gmail 18 send, reply, forward, read, search, list, create draft, update draft, send draft, delete draft, mark read, list filters, create label, list labels, update label, delete label, label message, save attachment to Drive
Calendar 6 list events, get event, create, update, delete, freebusy
Contacts 7 search, get, list, create, update, delete, directory search
Drive 3 search, read file, create folder
Sheets 13 read, update, append, create, delete, add tab, rename tab, delete tab, clear, find rows, format range, format table, batch update
Docs 5 get, write, batch update, create, delete
Slides 4 get, create, batch update, delete
Tasks 6 list task lists, list tasks, create, update, complete, delete
Generic 1 gws_run — fallback for any GWS API not covered above
Auth 1 OAuth login and status

64 tools total. All tools support shared (team) Drives.

Key tool details

gmail_create_draft / gmail_update_draft — Create or replace a Gmail draft. Constructs RFC 2822 MIME messages from structured parameters (to, subject, body, cc, bcc) and base64url-encodes them. gmail_update_draft preserves threading automatically — if no thread_id is provided, it fetches the existing draft's thread ID before replacing the message.

gmail_read — Full MIME payload by default. Pass text_only: true for a compact view (flattened from/to/cc/subject/date, decoded text body with HTML fallback, attachment metadata) that avoids base64 payloads overflowing the response — typically ~2% of the full size. max_body_chars truncates the body with a marker (implies text_only).

gmail_search / gmail_list — Results are flattened to {id, threadId, from, to, subject, date, snippet, labelIds} per message instead of the raw metadata payload.

gmail_send_draft / gmail_delete_draft — Send or permanently delete an existing draft by its draft ID. gmail_send_draft sends a reviewed draft as-is and removes it from Drafts (no orphaned draft left behind), completing the create → review → send loop. gmail_delete_draft deletes immediately (does not move to Trash).

gmail_mark_read — Marks messages as read by removing the UNREAD label. Also supports adding/removing arbitrary labels (STARRED, IMPORTANT, etc.) via add_labels and remove_labels arrays. Pass message_id for a single message, or message_ids (up to 1000) to modify a batch in one API call via users.messages.batchModify. Removes UNREAD by default when no label arrays are given.

gmail_list_filters — Reads the filters a mailbox already has, so you can see what automation exists before adding more. Reading filters works under gmail.modify.

Creating and deleting filters is not currently exposed. Google accepts only gmail.settings.basic on users.settings.filters.create and .delete, and gmail.modify does not carry it, so those calls fail with insufficient scopes regardless of what the caller does. Rather than ship two tools that can only fail, they are withheld until that scope is granted. Gmail filters are also immutable, so when they return, "editing" one means create new + delete old.

gmail_save_attachment_to_drive — Fetches an attachment from Gmail and uploads it directly to Drive server-side. No base64 data flows through the conversation. Uses async file I/O with guaranteed temp file cleanup via try/finally.

calendar_list_events — Compact view by default: per event you get id, title, times, location, a plain-text description (HTML stripped, truncated at 500 chars, tune with max_description_chars), the organizer, an attendee count plus your own response status, video join links (Meet, or Zoom and friends from conference data), a recurring flag, and attachments. Meetings with 10 or fewer attendees keep their full roster, so a 1:1 still tells you who it's with; larger meetings collapse to the count. Roughly 85% smaller than the raw payload on a busy calendar. Pass full: true for the raw Calendar API response.

calendar_get_event — Full event details with the description converted to plain text. Pass full: true to keep the original HTML.

drive_search — Searches across both personal and shared Drives. Supports full Drive query syntax including folder parents, mimeType filters, and name matching.

drive_create_folder — Creates a folder in Drive, optionally inside a parent folder.

drive_read_file — Reads the text content of any file in Drive by file ID. Routes by mimeType:

  • Google Docs → plain text extraction
  • Google Sheets → row/column data (A1:Z1000)
  • Google Slides → slide structure with placeholder maps and text
  • Office formats (.docx, .xlsx, .pptx) → server-side conversion to native Google format, read converted copy, then delete temp copy (guaranteed cleanup via try/finally)
  • Plain text / CSV (text/plain, text/csv) → raw content fetch
  • Unsupported types (PDF, images, etc.) → returns { error: "Unsupported file type: <mimeType>" }

docs_get — Three modes:

  • text (default): plain text with [image:<id>] placeholders for inline images, best for reading/summarizing
  • index: text with startIndex/endIndex character positions plus inline object references, use before positional edits
  • full: raw API response, for debugging or style operations

All modes include the inlineObjects metadata map (contentUri, size, margins, crop, border) when images are present.

docs_create / sheets_create — Return stripped responses with only essential fields:

  • docs_create → { documentId, title }
  • sheets_create → { spreadsheetId, title, spreadsheetUrl }

slides_get / slides_create — Return trimmed responses (no masters, layouts, geometry, styling). Each slide includes:

  • placeholder_map: maps standard types (TITLE, BODY, SUBTITLE) to objectIds
  • elements: all shapes — both standard placeholders and custom text boxes
  • Empty placeholders are included so callers can insert text immediately after create without a redundant get call

sheets_read — Returns normalized data:

  • columnCount derived from the widest row (handles empty leading rows correctly)
  • All rows padded to uniform column count with empty strings

sheets_append — Uses direct Sheets API (spreadsheets.values.append) to preserve 2D array structure. Each inner array becomes a separate row.

docs_write — Uses batchUpdate API with insertText, correctly handles newlines, em dashes, and unicode characters.

gws_run — Fallback tool for any Google Workspace API not covered by the dedicated tools. Accepts service, resource, method, params, and JSON body. Use only when no dedicated tool exists.

Setup (Extension — Claude Desktop)

1. Create a Google Cloud project

Go to Google Cloud Console and create a new project (or use an existing one).

2. Enable Google Workspace APIs

Enable each API you plan to use in your project. Click the links below and hit Enable on each page:

3. Configure OAuth consent screen

Go to OAuth consent screen:

  1. Select External user type
  2. Fill in the app name (e.g. "Google Workspace CLI") and your email
  3. Save and continue through all screens
  4. Under Test users, click Add users and add your Google account email

4. Create OAuth credentials

Go to Credentials:

  1. Click Create CredentialsOAuth client ID
  2. Application type: Desktop app
  3. Click Create
  4. Copy the Client ID and Client Secret

5. Configure OAuth credentials

cp .env.example .env

Open .env and fill in your Client ID and Client Secret from the previous step.

6. Build the extension

pnpm install
pnpm run build
pnpm run build:extension

This produces google-workspace-mcp.mcpb.

7. Install in Claude Desktop

Open Claude Desktop → Settings → Extensions → Install from file → select google-workspace-mcp.mcpb.

When the extension loads for the first time, a browser window opens automatically for Google OAuth login. Sign in and authorize the app. After that, all tools are ready to use.

Note: If your app is in testing mode (unverified), you'll see a "Google hasn't verified this app" warning. Click AdvancedGo to <app name> (unsafe) to proceed. This is safe for personal use.

Setup (HTTP Server — Claude Code / standalone)

1. Complete steps 1–5 above

2. Install and build

pnpm install
pnpm run build

3. Authenticate

With the env vars from step 5 set, run:

./bin/gws-aarch64-apple-darwin/gws auth login -s drive,gmail,sheets,calendar,docs,slides,people,tasks

4. Start the server

node server/index.js

The MCP server starts on http://localhost:39147/mcp (override with PORT env var).

5. Connect Claude Code

claude mcp add google-workspace --transport http http://localhost:39147/mcp

Or add to Claude Desktop MCP config:

{
  "mcpServers": {
    "google-workspace": {
      "type": "streamable-http",
      "url": "http://localhost:39147/mcp"
    }
  }
}

Environment Variables

Variable Default Description
PORT 39147 HTTP server port
GWS_OAUTH_CLIENT_ID OAuth client ID
GWS_OAUTH_CLIENT_SECRET OAuth client secret

Architecture

src/
├── create-server.ts      # Shared MCP server factory (accepts optional per-session client)
├── extension.ts          # Stdio entry point (.mcpb extension, auto-auth on startup)
├── index.ts              # HTTP entry point (StreamableHTTP, /health + /mcp endpoints)
├── gws-client.ts         # Wrapper around the gws CLI binary, DEFAULT_SERVICES constant
└── tools/
    ├── response.ts       # Response helpers (JSON formatting, 900KB truncation)
    ├── auth.ts           # OAuth login (browser-based, no gcloud needed)
    ├── gmail.ts          # Gmail tools (drafts, mark read, attachments to Drive)
    ├── calendar.ts       # Calendar tools
    ├── contacts.ts       # Contacts / People API tools
    ├── drive.ts          # Drive tools (search, read file, create folder)
    ├── sheets.ts         # Sheets tools (normalized reads, direct API append)
    ├── docs.ts           # Docs tools (text/index/full modes, inline image metadata)
    ├── slides.ts         # Slides tools (trimmed responses, placeholder maps)
    ├── tasks.ts          # Google Tasks tools (lists, CRUD, complete)
    ├── generic.ts        # Generic gws_run fallback
    └── index.ts          # Tool registry (flat Map<name, handler>)

The server wraps the gws CLI binary, which handles OAuth token management and API discovery. Each tool either uses client.helper() for high-level CLI commands or client.api() for direct Google API calls.

The extension (extension.ts) runs via stdio for Claude Desktop .mcpb bundles. The HTTP server (index.ts) runs as a standalone process for Claude Code or other MCP clients. Both share the same createMcpServer() factory.

Key implementation details

  • Shared Drive support: All Drive API calls include supportsAllDrives: true (and includeItemsFromAllDrives: true for list operations) so files on team Drives are accessible
  • Sandbox compatibility: Sets cwd: os.tmpdir() and GOOGLE_WORKSPACE_CLI_CONFIG_DIR for Claude Desktop's read-only filesystem
  • OAuth credentials: Reads from env vars, falls back to bundled oauth.json (injected at build time by scripts/build-extension.sh)
  • Auto-auth: Extension checks auth status and scope coverage on startup, opens browser for OAuth login if needed (non-blocking — MCP server starts immediately)
  • X-User-Token support: HTTP server accepts X-User-Token header to create per-session clients with pre-obtained access tokens (via GOOGLE_WORKSPACE_CLI_TOKEN env var)
  • Response truncation: All responses capped at 900KB to stay within context limits
  • Context optimization: docs_get, slides_get, and sheets_read aggressively strip metadata to minimize context usage. docs_get text mode reduces ~50KB API responses to ~2-3KB. slides_get strips masters/layouts/geometry/styling. sheets_read uses the values-only API endpoint.
  • Inline image metadata: docs_get includes inlineObjects map with image metadata (contentUri, size, margins) without embedding actual image bytes
  • Slides trimming: Strips masters, layouts, geometry, and styling from API responses — returns only objectIds, placeholder types, and text content
  • Office file reading: drive_read_file copies Office files with explicit target mimeType to trigger server-side conversion, reads the native copy, then deletes it (guaranteed cleanup via try/finally)
  • Unsupported type guard: drive_read_file only fetches raw content for text/plain and text/csv — all other non-native types return a clean error instead of binary data
  • Platform support: macOS (arm64, x64), Linux (x64), Windows (x64)

Development

pnpm run dev    # Watch mode — recompiles on change

License

MIT

Capabilities

gws-mcp__gmail_delete_label

Delete a Gmail label. Takes the label ID (from gmail_list_labels), not the label name. This removes the label from every message that carries it; the messages themselves are not deleted. System labels (INBOX, UNREAD, SENT) cannot be deleted.

Parameters

label_idstring/ The label ID to delete (from gmail_list_labels)
gws-mcp__gmail_label_message

Add or remove labels on one or more messages. Removing the INBOX label archives a message; removing UNREAD marks it read. Label IDs come from gmail_list_labels. To only flip read state, gmail_mark_read is the narrower tool.

Parameters

add_labelsarray/ Label IDs to add, e.g. ["Label_12"]
message_idstring/ A single message ID to modify
message_idsarray/ Several message IDs to modify in one call
remove_labelsarray/ Label IDs to remove, e.g. ["INBOX"] to archive or ["UNREAD"] to mark read
gws-mcp__gmail_list_labels

List every label in the mailbox, system and user-created, with each label's ID, name and type. Use this to find the label ID that gmail_label_message, gmail_update_label and gmail_delete_label need.

gws-mcp__gmail_update_label

Rename an existing Gmail label, or change its visibility. Takes the label ID (from gmail_list_labels), not the label name. Renaming a label keeps it on every message already labelled with it.

Parameters

namestring/ New label name. Nested labels use '/' (e.g. 'Alerts/Invoices')
label_idstring/ The label ID to update (from gmail_list_labels)
label_list_visibilitystring/ Whether the label shows in the label list: labelShow, labelShowIfUnread, or labelHide
message_list_visibilitystring/ Whether the label shows on messages in the message list: show or hide
gws-mcp__sheets_clear

Clear the values in a range, leaving the tab and its formatting in place. This is the non-destructive way to empty a tab or a block of cells — use it instead of deleting and recreating a tab, which throws away the tab's structure along with its data.

Parameters

rangestring/ Range to clear in A1 notation. A bare tab name clears the whole tab (e.g. "Inventory"), or clear a block with "Inventory!A2:D"
spreadsheet_idstring/ The spreadsheet ID
gws-mcp__sheets_delete_tab

Delete a tab (sheet) and everything in it from a spreadsheet. Takes the tab's current title. THIS DESTROYS EVERY ROW IN THE TAB and cannot be undone through the API. To empty a tab without losing it, use sheets_clear instead. To delete the whole spreadsheet file, use sheets_delete.

Parameters

titlestring/ Title of the tab to delete, with all of its rows
spreadsheet_idstring/ The spreadsheet ID
gws-mcp__sheets_rename_tab

Rename a tab (sheet) inside a Google Sheets spreadsheet. Takes the tab's current title, not its sheetId. Renaming changes only the label: every row, formula and value in the tab is untouched. Ranges that name the old title will stop resolving, so update any saved ranges afterwards.

Parameters

titlestring/ Current title of the tab to rename
new_titlestring/ New title for the tab
spreadsheet_idstring/ The spreadsheet ID
gws-mcp__sheets_find_rows

Find the rows in a spreadsheet range whose value in one column matches what you are looking for, and get back their ROW NUMBERS. Use this instead of reading a whole sheet and filtering the values yourself: on any real sheet that burns context on rows nobody asked for. Searches MANY values in a single call, so looking up twenty customers is one call and not twenty. Each match comes back with its 1-based sheet row number and a ready-made A1 range for that row, which is what lets a find be followed directly by a sheets_update. Values that matched nothing are listed separately, so an empty result cannot be mistaken for a broken call.

Parameters

matchstring/ "exact" (default) compares the whole cell, case-sensitively, after trimming both sides. "contains" and "prefix" are substring tests and are case-INsensitive. Exact is the default because a lookup that quietly folded case would make two different rows interchangeable without ever saying so.
rangestring/ The range to search in A1 notation, e.g. "Sheet1!A:D" for whole columns, "Sheet1!A1:D500" for a block, or a bare tab name for the whole tab. Row numbers in the result are absolute sheet rows, so a range starting at A10 reports its first data row as 11.
columnstring/ Which column to match on: a header name taken from the first row of the range ("Email"), or an A1 column letter ("B").
valuesarray/ The values to look for. Pass every value you need in ONE call, e.g. ["[email protected]", "[email protected]"].
max_resultsnumber/ Maximum matching rows returned per searched value. Default 50. A capped result says truncated: true, because a silent truncation reads exactly like a complete answer.
has_header_rowboolean/ Default true: the first row of the range is headers, is used to resolve a column name, and is never returned as a match. Set false when the range is pure data.
spreadsheet_idstring/ The spreadsheet ID
gws-mcp__sheets_format_table

Make a spreadsheet table readable in one call: column widths, wrapped and top-aligned cells, a styled and frozen header row, and hairline borders. This is the pass to run on ANY sheet a person is going to open. Values written through sheets_update and sheets_append carry no formatting at all, and the untouched default is columns 100px wide with every long cell truncated to a slit, so a sheet with entirely correct data is routinely unreadable and the reader never learns there was more text. Applies everything as one atomic batch. Use sheets_format_range for specific styling on top, or instead of this when you do not want the whole opinionated pass.

Parameters

wrapboolean/ Default true: wrap and top-align the body so rows grow to fit their content. Row heights are deliberately never set, because a fixed height overrides auto-fit and re-clips the text wrapping just unclipped.
rangestring/ The table, in A1 notation, e.g. "Sheet1!A1:E60", or a bare tab name for the whole tab. Include the header row.
bandedboolean/ Default false. Tint alternating body rows.
trim_gridboolean/ Default false. DELETES the rows and columns outside the range, which is what makes a sheet look authored rather than dumped. Destructive and opt-in, and it needs a fully bounded range so there is an end to trim from.
header_rowsnumber/ How many rows at the top of the range are headers. Default 1. Use 0 for a table with no header, which skips both the header styling and the freeze.
column_widthsarray/ Pixel widths, left to right, e.g. [250, 400, 400]. Columns you do not name get default_width. This is the single highest-value change on any sheet with prose in it.
default_widthnumber/ Width for columns not named in column_widths. Default 200.
freeze_headerboolean/ Default true: keep the header rows visible while scrolling. Only rows are ever frozen, never columns, because a frozen column makes merging across it illegal and would take an entire later batch down with it.
spreadsheet_idstring/ The spreadsheet ID
gws-mcp__sheets_update

Update specific cells in a Google Sheets spreadsheet. Overwrites existing values in the specified range.

Parameters

rangestring/ Cell range in A1 notation (e.g., "Sheet1!A1:B2")
valuesarray/ 2D array of values to write (rows of columns), e.g., [["A1","B1"],["A2","B2"]]
parse_formulasboolean/ Allow values to be stored as live formulas. Default false, which writes a leading = or + literally. Only set true when the caller explicitly asked for a formula — never for text taken from email, documents, or the web.
spreadsheet_idstring/ The spreadsheet ID
value_input_optionstring/ How Sheets interprets the values. USER_ENTERED (default) parses numbers, dates and booleans as typing them would, with formula-prefixed text kept inert unless parse_formulas is set. RAW stores every value verbatim as text: formulas never evaluate, but numbers arrive as text and break SUM/charts — use it only when literal-text semantics are the point.
gws-mcp__sheets_create

Create a new Google Sheets spreadsheet.

Parameters

titlestring/ Title for the new spreadsheet
headersarray/ Optional header row values, e.g., ["Name", "Email", "Date"]
gws-mcp__sheets_add_tab

Add a new tab (sheet) to an existing Google Sheets spreadsheet. Use sheets_create to make a whole new spreadsheet file; use this to add a tab inside one. Returns the new tab's sheetId and title.

Parameters

titlestring/ Title for the new tab
headersarray/ Optional header row values written to row 1 of the new tab, e.g., ["Name", "Email", "Date"]
spreadsheet_idstring/ The spreadsheet ID
gws-mcp__sheets_delete

Delete a Google Sheets spreadsheet. This permanently removes the file from Drive.

Parameters

spreadsheet_idstring/ The spreadsheet ID to delete
gws-mcp__docs_get

Get the content of a Google Doc. Three modes: "text" (default) returns plain text — use for reading/summarizing. "index" returns text with startIndex/endIndex — use before positional edits (insertText at index, deleteContentRange). "full" returns the raw API response — use only for debugging or style operations.

Parameters

modestring/ "text" (default): plain text. "index": text with character positions for edits. "full": raw API response.
document_idstring/ The Google Docs document ID (from the URL)
gws-mcp__docs_write

Insert text at the beginning of a Google Doc. To append or edit at a specific position, use docs_get (mode 'index') then docs_batch_update.

Parameters

textstring/ Text content to write to the document
document_idstring/ The Google Docs document ID
gws-mcp__docs_batch_update

Apply batch updates to a Google Doc. Supports inserting text, replacing text, deleting content ranges, and other document modifications. Uses the Google Docs API batchUpdate format.

Parameters

requestsarray/ Array of update request objects. Each can be: insertText ({ insertText: { location: { index: 1 }, text: "Hello" } }), replaceAllText ({ replaceAllText: { containsText: { text: "old", matchCase: true }, replaceText: "new" } }), deleteContentRange ({ deleteContentRange: { range: { startIndex: 1, endIndex: 10 } } })
document_idstring/ The Google Docs document ID
gws-mcp__docs_create

Create a new Google Doc.

Parameters

titlestring/ Title for the new document
gws-mcp__docs_delete

Delete a Google Doc. This permanently removes the document from Drive.

Parameters

document_idstring/ The document ID to delete
gws-mcp__gws_auth_setup

Check or manage Google Workspace authentication. In HTTP mode, auth is handled via the MCP OAuth flow. In extension/stdio mode (Claude Desktop), use action 'login' to authenticate or re-authenticate with updated scopes.

Parameters

actionstring/ Action to perform: 'status' (default) checks auth state, 'login' triggers browser-based OAuth login (extension/stdio mode only).
servicesstring/ Comma-separated services to request scopes for (e.g. 'drive,gmail,tasks'). Only used with action 'login'. Defaults to all supported services.
gws-mcp__gmail_read

Read a specific email message by its ID. By default returns the full message including headers, body, and metadata. Use text_only for a compact view (flattened headers, decoded text body, attachment metadata) that avoids large MIME/base64 payloads.

Parameters

text_onlyboolean/ Return a compact view instead of the raw MIME payload: flattened from/to/cc/subject/date headers, the decoded text/plain body (falls back to tag-stripped text/html), and attachment metadata (filename, mimeType, attachmentId). Recommended for triage — avoids base64 attachment data overflowing the response.
message_idstring/ The Gmail message ID to read
max_body_charsnumber/ Truncate the returned body text to this many characters (adds a truncation marker). Implies text_only.
gws-mcp__gmail_search

Search Gmail messages using Gmail search syntax. Returns matching messages with flattened from/to/subject/date fields plus snippet and labels. Supports queries like "from:[email protected]", "subject:proposal", "after:2024/01/01", "has:attachment", "label:important".

Parameters

querystring/ Gmail search query (e.g., "from:[email protected] subject:Q4 proposal", "is:unread after:2024/06/01")
max_resultsnumber/ Maximum number of messages to return (default: 10)
gws-mcp__gmail_list

List recent emails from the inbox. Optionally filter by label. Returns message IDs with flattened from/to/subject/date fields plus snippet and labels.

Parameters

labelstring/ Label to filter by (e.g., "INBOX", "SENT", "STARRED", "IMPORTANT", or custom label). Defaults to INBOX.
max_resultsnumber/ Maximum number of messages to return (default: 10)
gws-mcp__gmail_send_draft

Send an existing Gmail draft by its draft ID. Use this to send a draft that was previously created with gmail_create_draft and reviewed — it sends the draft as-is and removes it from the Drafts folder (no orphaned draft). Returns the sent message metadata.

Parameters

draft_idstring/ The Gmail draft ID to send
gws-mcp__gmail_delete_draft

Permanently delete a Gmail draft by its draft ID. This does not move the draft to Trash — it is removed immediately. Use gmail_send_draft to send a draft instead of deleting it.

Parameters

draft_idstring/ The Gmail draft ID to delete
gws-mcp__gmail_update_draft

Update an existing draft email in Gmail. This fully replaces the draft's message content (Gmail API does not support partial edits). If thread_id is omitted, the tool preserves the existing thread automatically.

Parameters

ccstring/ CC recipients, comma-separated
tostring/ Recipient email address(es), comma-separated
bccstring/ BCC recipients, comma-separated
bodystring/ Plain-text email body. When html_body is also given, this becomes the text/plain alternative part shown by plain-text clients.
subjectstring/ Email subject line
draft_idstring/ The Gmail draft ID to update
html_bodystring/ HTML email body. The message is sent as multipart/alternative with a text/plain fallback part (body if provided, otherwise text derived from the HTML), so plain-text clients still render something readable.
thread_idstring/ Thread ID to preserve threading. If omitted, the existing draft's thread is preserved automatically.
gws-mcp__gmail_reply

Reply to an existing email thread in Gmail.

Parameters

bodystring/ Reply body text (plain)
html_bodystring/ HTML reply body. Sent as text/html with no plain-text alternative part (this path hands quoting and threading to a single-part composer); the original message is quoted with Gmail styling. Provide body or html_body, not both.
message_idstring/ The Gmail message ID to reply to
gws-mcp__gmail_forward

Forward an existing email to another recipient.

Parameters

tostring/ Recipient email address to forward to
bodystring/ Optional plain-text note included above the forwarded message
html_bodystring/ Optional HTML note included above the forwarded message. Sent as text/html with no plain-text alternative part; the forwarded block is formatted with Gmail styling. Provide body or html_body, not both.
message_idstring/ The Gmail message ID to forward
gws-mcp__gmail_mark_read

Mark one or more Gmail messages as read by removing the UNREAD label. Can also add or remove other labels. Pass message_id for a single message (returns the modified message) or message_ids for a batch (up to 1000, single API call via users.messages.batchModify).

Parameters

add_labelsarray/ Label IDs to add (e.g., ["STARRED", "IMPORTANT"]). Optional.
message_idstring/ A single Gmail message ID to modify. Provide either this or message_ids.
message_idsarray/ Multiple Gmail message IDs to modify in one batch call (max 1000). Provide either this or message_id.
remove_labelsarray/ Label IDs to remove (e.g., ["UNREAD", "INBOX"]). Defaults to ["UNREAD"] if neither add_labels nor remove_labels is provided.
gws-mcp__gmail_list_filters

List all Gmail filters (settings > filters) with their criteria and actions. Use this to find a filter's ID before deleting it, or to check what automation already exists before creating a new filter.

gws-mcp__gmail_create_label

Create a Gmail label. Nested labels use '/' in the name (e.g. 'Alerts/Nativo'). Returns the created label including its ID, which can be used with gmail_create_filter or gmail_mark_read. To list existing labels, use gws_run with resource users.labels.

Parameters

namestring/ The label name to create
gws-mcp__gmail_save_attachment_to_drive

Save a Gmail attachment directly to Google Drive. Use gmail_read first to get attachment metadata (filename, mimeType, attachmentId) from the message parts. The file is fetched from Gmail and uploaded to Drive server-side — no base64 data flows through the conversation. Returns the Drive file metadata including a web link.

Parameters

filenamestring/ Filename to save as in Drive (e.g., 'report.xlsx')
message_idstring/ The Gmail message ID that contains the attachment
attachment_idstring/ The attachment ID from the message part's body.attachmentId field
parent_folder_idstring/ Optional Drive folder ID to save into. If omitted, saves to the root of My Drive.
gws-mcp__calendar_list_events

List upcoming events from a Google Calendar. By default returns a compact view per event: id, title, start/end, location, plain-text description (HTML stripped, truncated), organizer email, attendee count plus your own response status, the full attendee roster when the meeting has 10 or fewer people, a recurring flag, attachments, and the video join link (Meet or conference-data providers like Zoom). Only large-meeting rosters, reminders, and raw HTML are dropped — use full for the raw Calendar API payload, or calendar_get_event for one event's complete detail.

Parameters

fullboolean/ Return the raw Calendar API response instead of the compact view: full attendee rosters, reminders, conferenceData, htmlLink, and original (often HTML) descriptions. On busy calendars this can be very large — prefer the default compact view for triage and agenda use.
querystring/ Free-text search query to filter events
time_maxstring/ End of time range (ISO 8601, e.g., "2024-06-30T23:59:59Z"). Defaults to 7 days from now.
time_minstring/ Start of time range (ISO 8601, e.g., "2024-06-01T00:00:00Z"). Defaults to now.
calendar_idstring/ Calendar ID (default: "primary" for the user's main calendar)
max_resultsnumber/ Maximum number of events to return (default: 20)
max_description_charsnumber/ In the compact view, truncate each event's plain-text description to this many characters (default: 500; adds a truncation marker). Set to 0 to omit descriptions entirely. Ignored when full is true.
gws-mcp__calendar_get_event

Get details of a specific calendar event by its event ID. Returns the full event (all attendees, reminders, conference data), with the description converted to plain text; use full for the original (often HTML) description.

Parameters

fullboolean/ Keep the description exactly as stored (often multi-KB HTML from Zoom/scheduling tools) instead of converting it to plain text.
event_idstring/ The calendar event ID
calendar_idstring/ Calendar ID (default: "primary")
gws-mcp__calendar_create_event

Create a new calendar event. Supports setting title, time, attendees, description, location, and Google Meet links.

Parameters

endstring/ End time in ISO 8601 format (e.g., "2024-06-15T15:00:00-07:00")
startstring/ Start time in ISO 8601 format (e.g., "2024-06-15T14:00:00-07:00")
summarystring/ Event title
add_meetboolean/ Attach a Google Meet video conference link to the event (default: false)
locationstring/ Event location (physical address or room name)
attendeesstring/ Comma-separated email addresses of attendees
calendar_idstring/ Calendar ID (default: "primary")
descriptionstring/ Event description or agenda
send_updatesstring/ Who to send invite notifications to (default: "all")
gws-mcp__calendar_update_event

Update an existing calendar event. Only provided fields are changed.

Parameters

endstring/ New end time (ISO 8601)
startstring/ New start time (ISO 8601)
summarystring/ New event title
event_idstring/ The calendar event ID to update
locationstring/ New event location
attendeesstring/ Comma-separated email addresses (replaces existing attendees)
calendar_idstring/ Calendar ID (default: "primary")
descriptionstring/ New event description
send_updatesstring/ Who to send update notifications to (default: "all")
gws-mcp__calendar_delete_event

Delete a calendar event by its event ID.

Parameters

event_idstring/ The calendar event ID to delete
calendar_idstring/ Calendar ID (default: "primary")
send_updatesstring/ Who to send cancellation notifications to (default: "all")
gws-mcp__calendar_freebusy

Check availability (free/busy) for one or more people over a time range. Useful for finding open slots to schedule meetings.

Parameters

emailsstring/ Comma-separated email addresses to check availability for
time_maxstring/ End of the time range to check (ISO 8601)
time_minstring/ Start of the time range to check (ISO 8601)
gws-mcp__contacts_search

Search Google Contacts by name, email, or phone number. Returns matching contacts with their details.

Parameters

querystring/ Search query (name, email, phone number, or company name)
max_resultsnumber/ Maximum number of contacts to return (default: 10)
gws-mcp__contacts_get

Get full details of a specific contact by their resource name.

Parameters

resource_namestring/ Contact resource name (e.g., "people/c1234567890")
gws-mcp__contacts_list

List contacts from the user's Google Contacts. Returns names, emails, phone numbers, and organizations.

Parameters

max_resultsnumber/ Maximum number of contacts to return (default: 20)
gws-mcp__sheets_batch_update

Apply a batch of structural and formatting changes to a spreadsheet, in ONE atomic call. This is the full Google Sheets batchUpdate pass-through and the escape hatch beneath the job-shaped tools: reach for sheets_format_range or sheets_format_table first, and come here for anything they do not cover (merges, borders, banding, copyPaste, inserting or deleting COLUMNS, duplicateSheet, protected ranges). TWO PROPERTIES THAT BITE. (1) Ranges here are a GridRange, which is 0-BASED and END-EXCLUSIVE: spreadsheet row 7 is startRowIndex 6, endRowIndex 7. That is the opposite convention from the A1 notation used to write the values. (2) The batch is ATOMIC: if one request is rejected the whole batch applies nothing, and the error names the failing request's index. Build the whole pass as one batch, fix the named index, re-send the whole thing. Note that empty reply objects are normal for formatting requests and mean ACCEPTED, not applied to what you meant.

Parameters

requestsarray/ Array of Sheets API batchUpdate request objects, applied in order. Common ones: updateSheetProperties (freeze rows, hide gridlines, tab colour), updateDimensionProperties (column width, row height), insertDimension and deleteDimension (add or remove rows and columns, and these SHIFT every index after them, so put them first), repeatCell (fonts, colour, wrap, alignment, number format), mergeCells, updateBorders, copyPaste, duplicateSheet. Example: [{ "updateDimensionProperties": { "range": { "sheetId": 0, "dimension": "COLUMNS", "startIndex": 1, "endIndex": 4 }, "properties": { "pixelSize": 400 }, "fields": "pixelSize" } }]
spreadsheet_idstring/ The spreadsheet ID
gws-mcp__sheets_format_range

Set fonts, colours, wrapping, alignment, padding, number formats and merges on spreadsheet cells. Takes a LIST of formatting instructions and applies all of them in one atomic call, so a whole formatting pass is one tool call rather than one call per range. Colours are ordinary hex (#RRGGBB) and are converted for you. Only the properties you actually set are touched; anything you leave out keeps whatever the cell already had. If you want a table to simply look readable, use sheets_format_table instead, which does the whole standard pass. For anything not covered here (borders, banding, protected ranges) use sheets_batch_update.

Parameters

formatsarray/ One or more formatting instructions, each applied to one or more ranges. Every field except "ranges" is optional and only the ones you set are changed. Fields: ranges (array of A1 strings, required, e.g. ["Sheet1!A1:D1", "Sheet1!A20:D20"]), bold (boolean), italic (boolean), strikethrough (boolean), font_family (string, e.g. "Inter"), font_size (number), text_color ("#RRGGBB"), background_color ("#RRGGBB"), horizontal_align (LEFT|CENTER|RIGHT), vertical_align (TOP|MIDDLE|BOTTOM), wrap (OVERFLOW|CLIP|WRAP), number_format (a pattern string such as "#,##0.00", "yyyy-mm-dd" or "0.0%"), padding ({top,right,bottom,left} in pixels), merge (boolean, merges each named range into a single cell). Example: [{"ranges":["Sheet1!A1:D1"],"bold":true,"background_color":"#F1F1F1"},{"ranges":["Sheet1!A2:D99"],"wrap":"WRAP"}]
spreadsheet_idstring/ The spreadsheet ID
gws-mcp__gmail_send

Send a new email via Gmail. Composes and sends an email message to the specified recipients.

Parameters

ccstring/ CC recipients, comma-separated
tostring/ Recipient email address(es), comma-separated
bccstring/ BCC recipients, comma-separated
bodystring/ Plain-text email body. When html_body is also given, this becomes the text/plain alternative part shown by plain-text clients.
subjectstring/ Email subject line
html_bodystring/ HTML email body. The message is sent as multipart/alternative with a text/plain fallback part (body if provided, otherwise text derived from the HTML), so plain-text clients still render something readable.
gws-mcp__gmail_create_draft

Create a draft email in Gmail without sending it. The draft can be reviewed and sent later from Gmail. Returns the draft ID and a link to open it in Gmail.

Parameters

ccstring/ CC recipients, comma-separated
tostring/ Recipient email address(es), comma-separated
bccstring/ BCC recipients, comma-separated
bodystring/ Plain-text email body. When html_body is also given, this becomes the text/plain alternative part shown by plain-text clients.
subjectstring/ Email subject line
html_bodystring/ HTML email body. The message is sent as multipart/alternative with a text/plain fallback part (body if provided, otherwise text derived from the HTML), so plain-text clients still render something readable.
gws-mcp__sheets_append

Append rows to the end of a Google Sheets spreadsheet.

Parameters

rangestring/ Target range for appending (default: first sheet). e.g., "Sheet1!A1"
valuesarray/ 2D array of rows to append, e.g., [["val1","val2"],["val3","val4"]]
parse_formulasboolean/ Allow values to be stored as live formulas. Default false, which writes a leading = or + literally. Only set true when the caller explicitly asked for a formula — never for text taken from email, documents, or the web.
spreadsheet_idstring/ The spreadsheet ID
value_input_optionstring/ How Sheets interprets the values. USER_ENTERED (default) parses numbers, dates and booleans as typing them would, with formula-prefixed text kept inert unless parse_formulas is set. RAW stores every value verbatim as text: formulas never evaluate, but numbers arrive as text and break SUM/charts — use it only when literal-text semantics are the point.
gws-mcp__contacts_create

Create a new contact in Google Contacts.

Parameters

namestring/ Full name of the contact
emailstring/ Email address
notesstring/ Notes about the contact
phonestring/ Phone number
titlestring/ Job title
companystring/ Company or organization name
gws-mcp__contacts_update

Update an existing contact. Only provided fields are changed.

Parameters

namestring/ Updated full name
emailstring/ Updated email address
notesstring/ Updated notes
phonestring/ Updated phone number
titlestring/ Updated job title
companystring/ Updated company name
resource_namestring/ Contact resource name (e.g., "people/c1234567890")
gws-mcp__contacts_delete

Delete a contact from Google Contacts.

Parameters

resource_namestring/ Contact resource name (e.g., "people/c1234567890")
gws-mcp__contacts_directory_search

Search the company's Google Workspace directory (all users in the organization). Useful for finding colleagues' contact info.

Parameters

querystring/ Search query (name, email, or department)
max_resultsnumber/ Maximum number of results (default: 10)
gws-mcp__drive_create_folder

Create a new folder in Google Drive.

Parameters

namestring/ Name for the new folder
parent_idstring/ Parent folder ID to create inside (optional, defaults to root)
gws-mcp__drive_search

Search for files in Google Drive. Returns file names, IDs, types, and modification dates.

Parameters

querystring/ Search query (Drive query syntax, e.g., "name contains 'report'" or "mimeType='application/vnd.google-apps.spreadsheet'")
page_sizenumber/ Maximum number of results to return (default: 20)
gws-mcp__drive_read_file

Read the text content of any file in Google Drive by file ID. Supports Google Docs, Sheets, Slides, Office formats (.docx/.xlsx/.pptx — auto-converted), and plain text files. Returns extracted text directly — no local filesystem needed.

Parameters

file_idstring/ The Google Drive file ID to read
gws-mcp__sheets_read

Read data from a Google Sheets spreadsheet. Returns cell values for the specified range.

Parameters

rangestring/ Cell range in A1 notation (e.g., "Sheet1!A1:D10", "A1:Z")
spreadsheet_idstring/ The spreadsheet ID (from the URL)
value_render_optionstring/ How values are rendered. FORMATTED_VALUE (default) returns what the cell displays. UNFORMATTED_VALUE returns the underlying typed value, which is how you tell a stored number from stored text. FORMULA returns the cell's formula where it has one — the only way to tell a live formula from text that merely looks like one, so use it to verify a write.
gws-mcp__slides_get

Get the content of a Google Slides presentation. Returns slide objectIds, placeholder types (TITLE/BODY/SUBTITLE), and text content — stripped of layout/styling data to fit context windows. Use the returned objectIds with slides_batch_update for edits.

Parameters

presentation_idstring/ The Google Slides presentation ID (from the URL)
gws-mcp__slides_create

Create a new Google Slides presentation. Returns the presentationId and a placeholder_map for each slide mapping placeholder types (TITLE, BODY, SUBTITLE) to their objectIds — use these with slides_batch_update insertText.

Parameters

titlestring/ Title for the new presentation
gws-mcp__slides_batch_update

Apply batch updates to a Google Slides presentation. Supports inserting text, replacing text, creating slides, deleting objects, and other modifications. Uses the Google Slides API batchUpdate format.

Parameters

requestsarray/ Array of update request objects. Examples: createSlide ({ createSlide: { slideLayoutReference: { predefinedLayout: "TITLE_AND_BODY" } } }), insertText ({ insertText: { objectId: "slideId", text: "Hello", insertionIndex: 0 } }), replaceAllText ({ replaceAllText: { containsText: { text: "old" }, replaceText: "new" } }), deleteObject ({ deleteObject: { objectId: "elementId" } })
presentation_idstring/ The presentation ID
gws-mcp__slides_delete

Delete a Google Slides presentation. This permanently removes the file from Drive.

Parameters

presentation_idstring/ The presentation ID to delete
gws-mcp__tasks_list

List all task lists for the authenticated user.

gws-mcp__tasks_list_tasks

List tasks in a specific task list. Returns task titles, statuses, due dates, and notes.

Parameters

show_hiddenboolean/ Include hidden/deleted tasks (default: false)
tasklist_idstring/ The task list ID (use tasks_list to find IDs, or '@default' for the default list)
show_completedboolean/ Include completed tasks (default: true)
gws-mcp__tasks_create

Create a new task in a task list.

Parameters

duestring/ Due date in RFC 3339 format (e.g., 2026-03-28T00:00:00Z)
notesstring/ Notes/description for the task
titlestring/ Title of the task
tasklist_idstring/ The task list ID (or '@default' for the default list)
gws-mcp__tasks_update

Update an existing task's title, notes, or due date.

Parameters

duestring/ New due date in RFC 3339 format
notesstring/ New notes for the task
titlestring/ New title for the task
task_idstring/ The task ID to update
tasklist_idstring/ The task list ID
gws-mcp__tasks_complete

Mark a task as completed.

Parameters

task_idstring/ The task ID to mark as complete
tasklist_idstring/ The task list ID
gws-mcp__tasks_delete

Delete a task from a task list.

Parameters

task_idstring/ The task ID to delete
tasklist_idstring/ The task list ID
gws-mcp__gws_run

FALLBACK ONLY — use dedicated tools first (gmail_*, calendar_*, drive_*, sheets_*, docs_*, slides_*, contacts_*). Only use gws_run when no dedicated tool exists for the operation, e.g. Chat, Admin, Tasks, or advanced API calls not covered by other tools. Commands follow the pattern: gws <service> <resource> <method>.

Parameters

bodyobject/ Request body for create/update operations (alias for json_body)
methodstring/ API method (e.g., list, get, create, update, delete)
paramsobject/ Query parameters as key-value pairs (e.g., { pageSize: 10, q: "search query" })
dry_runboolean/ Preview the request without executing it
servicestring/ Google Workspace service (e.g., calendar, chat, admin, classroom, contacts, drive, gmail, sheets, docs, slides)
page_allboolean/ Fetch all pages of results (default: false, max 10 pages)
resourcestring/ API resource. Nested resources use dotted paths matching the API's REST structure — Gmail resources live under users (users.messages, users.drafts, users.labels, users.messages.attachments), not bare names like 'drafts'. Top-level examples: events (calendar), files (drive), spaces (chat).
json_bodyobject/ Request body for create/update operations (alias: body)

Connect

Add this to your MCP client config to access all integrations through the gateway.

{
  "mcpServers": {
    "datatorag": {
      "url": "https://datatorag.com/mcp"
    }
  }
}