Google Workspace MCP VE
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| ALLOWED_FILE_DIRS | No | Colon-separated allowlist for local file reads | |
| USER_GOOGLE_EMAIL | No | Default email for single-user auth | |
| WORKSPACE_MCP_URL | No | Remote MCP endpoint URL for CLI | |
| GOOGLE_PSE_API_KEY | No | API key for Programmable Search Engine | |
| MCP_ENABLE_OAUTH21 | No | 'true' to enable OAuth 2.1 multi-user support | |
| WORKSPACE_MCP_HOST | No | Bind host — default '0.0.0.0' | |
| WORKSPACE_MCP_PORT | No | Listening port — default '8000' | |
| GOOGLE_PSE_ENGINE_ID | No | Search Engine ID for PSE | |
| OAUTH_ALLOWED_ORIGINS | No | Comma-separated additional CORS origins | |
| GOOGLE_OAUTH_CLIENT_ID | Yes | OAuth client ID from Google Cloud | |
| WORKSPACE_EXTERNAL_URL | No | External URL for reverse proxy setups | |
| WORKSPACE_MCP_BASE_URI | No | Base server URI (no port) — default 'http://localhost' | |
| WORKSPACE_ATTACHMENT_DIR | No | Downloaded attachments dir — default '~/.workspace-mcp/attachments/' | |
| EXTERNAL_OAUTH21_PROVIDER | No | 'true' for external OAuth flow with bearer tokens | |
| GOOGLE_CLIENT_SECRET_PATH | No | Custom path to 'client_secret.json' | |
| GOOGLE_OAUTH_REDIRECT_URI | No | Override OAuth callback URL — default auto-constructed | |
| GOOGLE_MCP_CREDENTIALS_DIR | No | Credential directory — default '~/.google_workspace_mcp/credentials' | |
| GOOGLE_OAUTH_CLIENT_SECRET | No | OAuth client secret for confidential clients; optional for public OAuth 2.1 PKCE clients | |
| OAUTH_CUSTOM_REDIRECT_URIS | No | Comma-separated additional redirect URIs | |
| OAUTHLIB_INSECURE_TRANSPORT | No | Set to '1' for development — allows 'http://' redirect | |
| WORKSPACE_MCP_STATELESS_MODE | No | 'true' for stateless container-friendly operation | |
| GOOGLE_SERVICE_ACCOUNT_KEY_FILE | No | Path to service account JSON key file (domain-wide delegation) | |
| GOOGLE_SERVICE_ACCOUNT_KEY_JSON | No | Inline service account JSON key (alternative to file) | |
| WORKSPACE_MCP_OAUTH_PROXY_STORAGE_BACKEND | No | 'memory', 'disk', or 'valkey' — see storage backends | |
| FASTMCP_SERVER_AUTH_GOOGLE_JWT_SIGNING_KEY | No | Custom encryption key for OAuth proxy storage; required for public OAuth 2.1 clients when GOOGLE_OAUTH_CLIENT_SECRET is omitted |
Capabilities
Features and capabilities supported by this server
| Capability | Details |
|---|---|
| tools | {
"listChanged": true
} |
| logging | {} |
| prompts | {
"listChanged": false
} |
| resources | {
"subscribe": false,
"listChanged": false
} |
| extensions | {
"io.modelcontextprotocol/ui": {}
} |
| experimental | {} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| start_google_authA | Manually initiate Google OAuth authentication flow. NOTE: This is a legacy OAuth 2.0 tool and is disabled when OAuth 2.1 is enabled. The authentication system automatically handles credential checks and prompts for authentication when needed. Only use this tool if:
In most cases, simply try calling the Google Workspace tool you need - it will automatically handle authentication if required. |
| search_gmail_messagesA | Search Gmail messages and return their IDs plus clickable web links. Use this to locate messages by subject/sender/date before calling get_gmail_message_content (single) or get_gmail_messages_content_batch (many). This tool returns IDs only, not bodies — fetch bodies in a second step. Requires the gmail.readonly OAuth scope. |
| get_gmail_message_contentA | Retrieve one Gmail message's headers and body by ID. Use this for a single message; for multiple IDs prefer get_gmail_messages_content_batch to avoid round trips. For an entire conversation use get_gmail_thread_content. Attachment bytes are not returned here — use get_gmail_attachment_content. Requires the gmail.readonly OAuth scope. |
| get_gmail_messages_content_batchA | Fetch many Gmail messages in one batch, chunked internally. Prefer this over calling get_gmail_message_content in a loop — uses the Gmail batch API (25 per request, auto-chunked) and falls back to sequential fetches if the batch call fails. Use format="metadata" when you only need headers for triage (cheaper + faster). Requires the gmail.readonly OAuth scope. |
| get_gmail_attachment_contentA | Download a Gmail attachment to disk (or expose via download URL). Side effects: writes a file to the configured attachment storage (stdio mode) or publishes a temporary download URL valid for 1 hour (HTTP mode). In stateless mode, no file is written and a base64 preview is returned instead. Attachment IDs are ephemeral — always re-fetch the parent message (get_gmail_message_content) just before calling this. Requires the gmail.readonly OAuth scope. |
| send_gmail_messageA | Sends an email using the user's Gmail account. Supports both new emails and replies with optional attachments. Supports Gmail's "Send As" feature to send from configured alias addresses. |
| draft_gmail_messageA | Creates a draft email in the user's Gmail account. Supports both new drafts and reply drafts with optional attachments. Supports Gmail's "Send As" feature to draft from configured alias addresses. |
| get_gmail_thread_contentA | Retrieve every message in one Gmail conversation thread. Use this when you need the whole back-and-forth (replies, forwards, quoted history) — for a single standalone message use get_gmail_message_content. For many threads at once use get_gmail_threads_content_batch. Requires the gmail.readonly OAuth scope. |
| get_gmail_threads_content_batchA | Fetch many Gmail threads in one batch, chunked internally. Prefer this over calling get_gmail_thread_content in a loop — uses the Gmail batch API (25 per request, auto-chunked) and falls back to sequential fetches if the batch call fails. Requires the gmail.readonly OAuth scope. |
| list_gmail_labelsA | List every label in the user's mailbox, split system vs user. Use this to discover label IDs before calling modify_gmail_message_labels / batch_modify_gmail_message_labels / manage_gmail_filter — label IDs (not names) are what those tools require. Requires the gmail.readonly OAuth scope. |
| manage_gmail_labelA | Create, update, or delete a Gmail label. Side effects: creates/mutates/deletes a label on the account — delete is destructive and unrecoverable. To only apply or remove labels from messages (not manage the labels themselves) use modify_gmail_message_labels instead. Requires the gmail.labels OAuth scope. |
| list_gmail_filtersA | List every server-side Gmail filter configured on the mailbox. Filters auto-apply actions (label, forward, archive) to incoming mail matching their criteria. Use this to audit or discover filter IDs before calling manage_gmail_filter for delete. Requires the gmail.settings.basic OAuth scope. |
| manage_gmail_filterA | Create or delete a server-side Gmail filter. Side effects: creates a persistent auto-action rule or permanently deletes one. Filter updates are not supported by the Gmail API — delete and recreate instead. Use list_gmail_filters first to inspect existing filters. Requires the gmail.settings.basic OAuth scope. |
| modify_gmail_message_labelsA | Add or remove labels on one Gmail message. Side effects: mutates the message's label set. Common recipes: remove "INBOX" to archive, add "TRASH" to delete (soft), add "STARRED" to star. For many messages at once use batch_modify_gmail_message_labels. To create/delete the labels themselves use manage_gmail_label. Requires the gmail.modify OAuth scope. |
| batch_modify_gmail_message_labelsA | Add or remove labels on many Gmail messages in one API call. Side effects: mutates label sets on every message in message_ids. Uses the Gmail batchModify endpoint (up to 1000 IDs per call — Gmail's limit, not enforced here). For single messages use modify_gmail_message_labels. Requires the gmail.modify OAuth scope. |
| search_drive_filesA | Search Drive (including shared drives) for files and folders. Free-text queries are auto-wrapped in |
| get_drive_file_contentA | Download a Drive file and return its text (auto-extracting per type). Use this when you need file text; for a URL to the raw bytes use get_drive_file_download_url, for metadata use get_file_metadata (in hosted clients) or list fields. Handles shared drives. Extraction: Google Docs/Sheets/Slides export to text/CSV; Office .docx/.xlsx/.pptx unzipped and parsed; PDFs extracted with pypdf (scanned PDFs fall back to a download hint); images returned as base64 for multimodal clients; other files decoded as UTF-8 or flagged binary. Requires the drive.readonly OAuth scope. |
| get_drive_file_download_urlA | Save a Drive file to disk (or expose a temporary URL). Side effects: writes a file to the configured attachment storage (stdio mode) or publishes a download URL valid for 1 hour (HTTP mode). For file text content use get_drive_file_content instead; use this when you specifically need the binary file or an export. Google-native files are exported — Docs → PDF or DOCX; Sheets → XLSX, PDF, or CSV; Slides → PDF or PPTX. Other files download as-is. Requires the drive.readonly OAuth scope. |
| list_drive_itemsA | List files in one Drive folder (children of folder_id). Use this to browse by folder; for content-based search use search_drive_files. Scoped to a folder's direct children. If drive_id is set, folder_id is interpreted inside that shared drive. Requires the drive.readonly OAuth scope. |
| create_drive_folderA | Create a new folder in Drive (or inside a shared drive). Side effects: creates a folder owned by the authenticated user (or by the shared drive when parent_folder_id lives in one). To upload files into the new folder use create_drive_file with folder_id set to the returned ID. Requires the drive.file OAuth scope. |
| create_drive_fileA | Upload a file to Drive from content, a URL, or a local path. Side effects: creates a new Drive file. To convert source files (Markdown, DOCX, etc.) into native Google Docs use import_to_google_doc instead. For a brand-new empty Google Doc/Sheet/Slide use create_doc/create_spreadsheet/create_presentation. Requires the drive.file OAuth scope. |
| import_to_google_docA | Convert a source file into a native Google Doc on upload. Drive performs the conversion server-side, preserving headings, lists, inline formatting, tables, etc. Use this (not create_drive_file) when you want a real Google Doc editable in the web UI. For adding content to an existing Doc use insert_doc_markdown or insert_doc_elements. Requires the drive.file OAuth scope. |
| get_drive_file_permissionsA | Inspect a Drive file's sharing permissions and public-link status. Use this to audit who can access a file before sharing externally. To change sharing use set_drive_file_permissions or manage_drive_access. For a quick public-vs-private check by filename use check_drive_file_public_access. Requires the drive.readonly OAuth scope. |
| check_drive_file_public_accessA | Search by filename and report whether the file is publicly linked. Quick helper for Google Docs embedding — a file must have "Anyone with the link" access before insert_doc_image can render it. If multiple files match the name, checks the first. For a specific file use get_drive_file_permissions. Requires the drive.readonly OAuth scope. |
| update_drive_fileA | Update a Drive file's metadata, folder parents, and flags. Side effects: mutates the file (rename, move via add/remove_parents, trash/untrash, star). Does NOT upload new content — for content use a native-app tool or create_drive_file. trashed=True is reversible with trashed=False until the file is permanently deleted. Requires the drive.file OAuth scope. |
| get_drive_shareable_linkA | Fetch the webViewLink and current permissions for a Drive item. Read-only — does NOT change sharing. To modify sharing use manage_drive_access. For a fuller permissions audit use get_drive_file_permissions. Requires the drive.readonly OAuth scope. |
| manage_drive_accessA | Grant, batch-grant, update, revoke, or transfer ownership on a Drive item. Side effects: all actions mutate permissions; transfer_owner permanently changes the file's owner. Notification emails are sent per send_notification. For read-only inspection use get_drive_file_permissions. Requires the drive.file OAuth scope (or higher for cross-domain transfers). |
| copy_drive_fileA | Duplicate a Drive file (including Google Docs/Sheets/Slides). Side effects: creates a new owned-by-caller file; formatting and content are preserved. For folders use copy_drive_folder (deep copy). For Google Docs specifically this is the standard "duplicate from template" pattern — copy, then edit via batch_update_doc. Requires the drive.file OAuth scope. |
| set_drive_file_permissionsA | Toggle link-sharing and common file-level sharing controls. Side effects: mutates sharing policy. Use this for high-level toggles ("anyone with the link", editor share rights, viewer copy-prevention). For per-user/group permission changes use manage_drive_access. At least one of the three flags must be set. Requires the drive.file OAuth scope. |
| copy_drive_folderA | Recursively copy a Drive folder (and all its contents) to a new location. Walks the source folder tree, creating the same structure under the destination and copying every file. Sequential to avoid rate-limit errors. |
| get_drive_revisionsA | List the revision history for a Drive file, newest first. Returns each revision's ID, modification timestamp, last-modifying user
(display name + email), size in bytes (when available), MIME type, and
whether it's pinned via Requires OAuth scope: Limitation: Google-native files (Docs, Sheets, Slides) expose revisions
in the API list but their binary content is not retrievable — only
non-native files (PDF, DOCX, images, etc.) support content restore. By
default, Drive retains up to 100 revisions or 30 days, whichever comes
first, unless a revision is pinned ( |
| restore_drive_revisionA | Restore a Drive file's content to a previous revision. Downloads the raw bytes of the specified revision and re-uploads them as the file's current content. This creates a NEW revision identical to the old one (it does not rewind the revision history — older revisions remain accessible). Original file ID, name, and sharing permissions are preserved. Requires OAuth scope: Limitation: Google-native files (Docs, Sheets, Slides — MIME type
|
| list_calendarsA | List every calendar the user owns or has access to. Use this to discover calendar IDs before calling get_events, manage_event, or create_calendar — calendar IDs (not names) are what those tools require. The user's main calendar is always addressable as "primary". Requires the calendar.readonly OAuth scope. |
| get_eventsA | Fetch events from a calendar — one by ID, or a filtered range. Two modes: (1) pass event_id to retrieve a single event (range/query params ignored); (2) omit event_id to list events in a time window, optionally filtered by keyword. For free/busy scanning across many calendars use query_freebusy instead. For creating/updating events use manage_event. Requires the calendar.readonly OAuth scope. |
| manage_eventA | Create, update, delete, or RSVP to a calendar event. Side effects: mutates calendar state on the account. Delete is destructive. Attendee email notifications follow send_updates. For read-only fetches use get_events; for focus-time blocks use manage_focus_time. Requires the calendar.events OAuth scope. |
| manage_out_of_officeA | Create, list, update, or delete Out of Office events. OOO events are a special event type that auto-declines conflicting invitations and sets Workspace presence to "Out of office". They live on the primary calendar only. For normal events use manage_event; for focus-time blocks use manage_focus_time. Side effects: mutating actions may auto-decline existing/incoming invites based on auto_decline_mode. Requires the calendar.events OAuth scope. |
| manage_focus_timeA | Create, list, update, or delete Focus Time events. Focus Time is a special event type that auto-declines conflicting invitations and (by default) sets Google Chat to Do Not Disturb for the duration. Lives on the primary calendar only. For regular events use manage_event; for OOO use manage_out_of_office. Side effects: mutating actions may auto-decline existing/incoming invites and flip chat presence. Requires the calendar.events OAuth scope. |
| query_freebusyA | Query busy-time windows across one or more calendars. Use this to find scheduling conflicts or free slots before creating an event — it returns only busy periods, not event details. For event details use get_events. This is the efficient way to compare availability across multiple people/rooms. Requires the calendar.readonly OAuth scope. |
| create_calendarA | Create a new secondary calendar owned by the user. Side effects: creates a new calendar and adds it to the user's calendar list. To add events use manage_event with the returned calendar_id. To share the calendar with others, use the Calendar web UI or ACL APIs (not exposed by this tool). Requires the full calendar OAuth scope. |
| search_docsA | Search for Google Docs by filename substring across the user's entire Drive (including shared drives and items shared with them). Use this for name-only lookups — it runs a Drive Requires OAuth scope: |
| get_doc_contentA | Retrieve Doc body text (native Google Docs or Drive-stored .docx). For native Google Docs uses the Docs API and walks tabs (including nested child tabs). For non-native Drive files (.docx, etc.) falls back to the Drive download + text extraction path. For markdown output use get_doc_as_markdown; for structural inspection (style, headings, objects) use inspect_doc_structure. Requires both drive.readonly and docs.readonly OAuth scopes. |
| list_docs_in_folderA | List all Google Docs (native Use this when you want to enumerate Docs inside a known folder (e.g.,
a team drive subfolder). For name-based search across the whole
Drive, use Only direct children are returned — subfolders are NOT recursed. Shared
drives are supported via Requires OAuth scope: |
| create_docA | Creates a new Google Doc and optionally inserts initial content. After creation, the document body starts at index 1. A new empty doc has total length 2 (one section break at index 0, one newline at index 1). To build a rich document after creation, use batch_update_doc with insert_text operations using end_of_segment=true to append content sequentially without calculating indices. Then call inspect_doc_structure to get exact positions before applying formatting in a separate batch call. |
| modify_doc_textA | Modifies text in a Google Doc - can insert/replace text and/or apply formatting in a single operation. TIP: To append text to the end of the document without calculating indices, set end_of_segment=true. This avoids index calculation errors. MARKDOWN MODE: Set format_as_markdown=True to parse For ordinary header/footer text, prefer update_doc_headers_footers. Only pass segment_id when you already have a real header/footer/footnote segment ID from inspect_doc_structure output. Do not guess IDs such as "kix.header" or "kix.footer". |
| find_and_replace_docA | Finds and replaces text throughout a Google Doc. No index calculation required. This is the safest way to update specific text in a document because it does not require knowing any indices. Use this tool when you need to:
For building documents from scratch, consider inserting text with unique placeholders via batch_update_doc, then using this tool to replace them. |
| insert_doc_elementsA | Insert a table, list, or page break into a Google Doc. For plain text or inline markdown use modify_doc_text (with format_as_markdown=True for rich output). For images use insert_doc_image. For Drive-file chips use insert_doc_file_chip. Note: index 0 is automatically bumped to 1 (to skip the opening section break). Requires the documents OAuth scope. |
| insert_doc_imageA | Insert an image into a Google Doc from Drive or an HTTPS URL. When image_source is a Drive file ID, its sharing MUST allow "Anyone with the link" — check with check_drive_file_public_access first. HTTPS URLs must serve image bytes directly (no redirects, login walls, or signed URLs). PNG/JPEG/GIF supported. Index 0 is auto-bumped to 1. Requires both docs and drive.readonly OAuth scopes. |
| update_doc_headers_footersA | Safely creates or updates header/footer text in a Google Doc. This is the default tool for header/footer content. Do NOT use batch_update_doc with create_header_footer just to set header/footer text; that low-level operation is only for advanced section-break workflows and can fail when the default header/footer already exists. This tool handles both creation and update in one call:
You do NOT need to create a header/footer separately before calling this tool. Simply call it with the desired content and it will work whether the header/footer exists or not. |
| batch_update_docA | Executes multiple low-level document operations in a single atomic batch update. For normal header/footer text, prefer update_doc_headers_footers. Only use create_header_footer here for advanced section-break layouts. RECOMMENDED WORKFLOW FOR BUILDING DOCUMENTS:To avoid index calculation errors, build documents in phases: PHASE 1 - INSERT ALL CONTENT (use end_of_segment=true, no index math): Append text, section breaks, and page breaks sequentially. Each operation appends to the end of the body. No index needed. Example batch: [ {"type": "insert_text", "end_of_segment": true, "text": "Report Title\n"}, {"type": "insert_text", "end_of_segment": true, "text": "\nExecutive Summary\n"}, {"type": "insert_text", "end_of_segment": true, "text": "Revenue grew 15%.\n"}, {"type": "insert_section_break", "end_of_segment": true, "section_type": "NEXT_PAGE"}, {"type": "insert_text", "end_of_segment": true, "text": "Detailed Analysis\n"} ] PHASE 2 - CREATE HEADERS/FOOTERS (if needed): For normal header/footer text, use update_doc_headers_footers (it auto-creates if missing and writes the content for you). Only include create_header_footer operations in a batch when you are intentionally managing advanced section-break-specific layouts. |
| inspect_doc_structureA | Essential tool for finding safe insertion points and understanding document structure. USE THIS FOR:
CRITICAL FOR TABLE OPERATIONS: ALWAYS call this BEFORE creating tables to get a safe insertion index. WHAT THE OUTPUT SHOWS:
WORKFLOW FOR TABLE INSERTION: Step 1: Call this function Step 2: Note the "total_length" value Step 3: Use an index < total_length for table insertion Step 4: Create your table FORMATTING WORKFLOW: After inserting all text via batch_update_doc with end_of_segment=true, call this tool with detailed=true to get exact start_index and end_index for every paragraph. Use those indices directly in format_text and update_paragraph_style operations in a second batch_update_doc call. HEADER/FOOTER WORKFLOW: For ordinary header/footer text, use update_doc_headers_footers. If you need low-level segment editing, call this tool first and use the real segment_id values returned under headers/footers. Do not invent IDs. The detailed output includes elements[].start_index and elements[].end_index with text_preview for each paragraph, making it easy to identify which ranges to format. |
| debug_docs_runtime_infoB | Return runtime/source information for diagnosing stale MCP server instances. This is a temporary diagnostic tool intended to verify which code checkout the running MCP server has loaded. |
| create_table_with_dataA | Creates a table and populates it with data in one reliable operation. CRITICAL: YOU MUST CALL inspect_doc_structure FIRST TO GET THE INDEX! MANDATORY WORKFLOW - DO THESE STEPS IN ORDER: Step 1: ALWAYS call inspect_doc_structure first Step 2: Use the 'total_length' value from inspect_doc_structure as your index Step 3: Format data as 2D list: [["col1", "col2"], ["row1col1", "row1col2"]] Step 4: Call this function with the correct index and data EXAMPLE DATA FORMAT: table_data = [ ["Header1", "Header2", "Header3"], # Row 0 - headers ["Data1", "Data2", "Data3"], # Row 1 - first data row ["Data4", "Data5", "Data6"] # Row 2 - second data row ] CRITICAL INDEX REQUIREMENTS:
DATA FORMAT REQUIREMENTS:
|
| debug_table_structureA | ESSENTIAL DEBUGGING TOOL - Use this whenever tables don't work as expected. USE THIS IMMEDIATELY WHEN:
WHAT THIS SHOWS YOU:
HOW TO READ THE OUTPUT:
WORKFLOW INTEGRATION:
|
| export_doc_to_pdfA | Export a Google Doc as PDF and save the PDF back into Drive. Side effects: creates a new PDF file in Drive (separate file from the Doc — the Doc itself is untouched). To download bytes without saving use get_drive_file_download_url with export_format="pdf". To convert the source to DOCX or other formats use get_drive_file_download_url. Requires both docs (read) and drive.file OAuth scopes. |
| update_paragraph_styleB | Apply paragraph-level formatting, heading styles, and/or list formatting to a range in a Google Doc. This tool can apply named heading styles (H1-H6) for semantic document structure, create bulleted or numbered lists with nested indentation, and customize paragraph properties like alignment, spacing, and indentation. All operations can be applied in a single call. |
| get_doc_as_markdownA | Reads a Google Doc and returns it as clean Markdown with optional comment context. Unlike get_doc_content which returns plain text, this tool preserves document formatting as Markdown: headings, bold/italic/strikethrough, links, code spans, ordered/unordered lists with nesting, and tables. When comments are included (the default), each comment's anchor text — the specific text the comment was attached to — is preserved, giving full context for the discussion. |
| insert_doc_tabA | Create a new tab in a multi-tab Google Doc. Side effects: creates a new empty tab (a sub-document) in the target Doc. Google Docs tabs (introduced Oct 2024) let one Doc hold multiple sub-documents. To list existing tabs + IDs use list_doc_tabs; to rename use update_doc_tab; to delete use delete_doc_tab. Requires the documents OAuth scope. |
| delete_doc_tabA | Delete a tab (and its entire sub-document) from a Google Doc. Side effects: PERMANENTLY removes the tab and all its content — UI-undo via Edit > Undo still works if the caller has the Doc open, but there is no API undo. To just rename a tab use update_doc_tab. Requires the documents OAuth scope. |
| update_doc_tabA | Rename an existing tab in a Google Doc. Changes the tab's display title only — does not move or delete its content. For creating tabs use insert_doc_tab; for deleting use delete_doc_tab. Requires the documents OAuth scope. |
| list_doc_tabsA | List all tabs in a Google Doc, including nested child tabs, as a flat tree. Google Docs tabs (launched Oct 2024) let a single document contain multiple
sub-documents organized hierarchically. Most doc-editing tools need a
Requires OAuth scope: |
| insert_doc_markdownA | Insert markdown-formatted content into a Google Doc with native styling. Converts markdown to Docs API batch requests so output renders with
real Docs styles (headings, bold, lists), not raw markdown. For plain
text insertion use modify_doc_text; for find-and-replace patterns use
find_and_replace_doc. Supports |
| insert_doc_linkA | Insert clickable hyperlink text at a given document index. Use this for a simple hyperlink; for a Drive-file smart chip use insert_doc_file_chip; for a person @mention chip use insert_doc_person_chip. Requires the documents OAuth scope. |
| insert_doc_person_chipA | Insert an @mention-style person chip at a specific position in a document. Writes the person's email as linked text (href = Requires OAuth scope: Note: The chip only renders correctly once a collaborator or the owner opens the doc in the Google Docs UI — Docs does the text-to-chip conversion client-side on render. The API always stores the raw linked email. Person resolution uses the email only; if the email doesn't match a Google account visible to the viewer, it falls back to plain linked text. |
| insert_doc_file_chipA | Insert a Drive-file smart chip at an index in a Google Doc. Side effect note: chip rendering happens client-side — the API stores a linked URL, and Google Docs upgrades it to a chip with filename/ icon/preview on the next render. For a person @mention use insert_doc_person_chip; for a plain hyperlink use insert_doc_link. Requires the documents OAuth scope. |
| get_doc_smart_chipsA | Extract every smart chip in a Google Doc — person mentions and rich links. Walks the document body, finds all Requires OAuth scope: Scope note: This inspects the main document body only. Chips inside
headers, footers, footnotes, or secondary tabs are not returned. Only
chips that have been rendered/saved by the Docs client appear here —
chips inserted programmatically via |
| apply_continuous_numberingA | Convert plain-text "N. " step prefixes in a Google Doc (or specific tab) into a real numbered list whose numbering continues across intervening prompt paragraphs and sub-bullet lists. Idempotent — safe to re-run on documents already processed. |
| list_document_commentsC | List all comments from a Google Document. |
| manage_document_commentA | Manage comments on a Google Document. Actions:
|
| list_spreadsheetsA | List accessible Google Sheets spreadsheets (most-recently-modified first). Use this as a discovery step when the user only has a spreadsheet name — the returned ID feeds get_spreadsheet_info, read_sheet_values, etc. For a broader Drive search by name use search_drive_files with file_type="sheet". Requires the drive.readonly OAuth scope. |
| get_spreadsheet_infoA | Inspect a spreadsheet's metadata (title, locale, tabs, sizes). Use this to discover sheet (tab) names and sheetIds before calling read_sheet_values, manage_sheet_tabs, or protect_sheet_range. Also surfaces conditional format counts per tab. Does not read cell values — use read_sheet_values for that. Requires the spreadsheets.readonly OAuth scope. |
| read_sheet_valuesA | Read cell values from an A1 range (optionally with formulas/notes). Output is capped at 50 rows for readability — widen the range or paginate manually for more. For writing use modify_sheet_values. For appending to a table use append_table_rows. Requires the spreadsheets.readonly OAuth scope. |
| modify_sheet_valuesA | Write, overwrite, or clear values in an A1 range. Side effects: overwrites existing cells in the exact range. To append new rows to a table use append_table_rows instead. For formatting use format_sheet_range. Requires the spreadsheets OAuth scope. |
| format_sheet_rangeA | Applies formatting to a range: colors, number formats, text wrapping, alignment, and text styling. Colors accept hex strings (#RRGGBB). Number formats follow Sheets types (e.g., NUMBER, CURRENCY, DATE, PERCENT). If no sheet name is provided, the first sheet is used. |
| manage_conditional_formattingA | Manages conditional formatting rules on a Google Sheet. Supports adding, updating, and deleting conditional formatting rules via a single tool. |
| create_spreadsheetA | Create a brand-new empty Google Spreadsheet in My Drive. Side effects: creates a new file owned by the authenticated user in My Drive root. To add tabs to an existing spreadsheet use create_sheet. To upload an existing .xlsx use create_drive_file or import_to_google_doc (for content) instead. Requires the spreadsheets OAuth scope. |
| create_sheetA | Add a new tab (sheet) to an existing spreadsheet. Side effects: appends a new tab at the end. To rename/reorder/delete tabs use manage_sheet_tabs. For a brand-new spreadsheet use create_spreadsheet. Requires the spreadsheets OAuth scope. |
| list_sheet_tablesA | List all structured tables (native Sheets tables) in a spreadsheet. A "table" here is the newer native Sheets Table feature, not any bounded range. Use this to discover table_id before calling append_table_rows. Requires the spreadsheets.readonly OAuth scope. |
| append_table_rowsA | Append rows to a structured Sheets table, auto-extending its range. Side effects: mutates the table — new rows are added after the last existing row and the table range grows to include them. Values are typed automatically: bool → boolean, numeric → number, strings starting with "=" → formula, otherwise string. For plain range writes use modify_sheet_values. Requires the spreadsheets OAuth scope. |
| resize_sheet_dimensionsC | Manages sheet-level dimension properties: resize columns/rows, auto-resize to fit content, freeze rows/columns, hide/unhide rows/columns, and insert/delete rows/columns. |
| add_sheet_data_validationA | Apply a data-validation rule to a range (dropdowns, bounds, formulas). Side effects: replaces any existing validation on the range. For conditional formatting (color rules) use manage_conditional_formatting. For protecting cells from edits use protect_sheet_range. Requires the spreadsheets OAuth scope. |
| add_sheet_named_rangeA | Define a named range that formulas and scripts can reference by name. Creates a persistent alias for a range — e.g., Requires OAuth scope: |
| protect_sheet_rangeA | Protect a range in a spreadsheet so unauthorized users cannot edit it. Adds a Sheets "Protected range" entry (Data > Protect sheets and ranges) restricting who can modify the cells. Two enforcement modes: strict (non-editors are blocked) or warning-only (a confirmation dialog appears, but edits are allowed). Use strict for financial data, formula cells, or anything where an accidental overwrite would corrupt downstream calcs. Requires OAuth scope: |
| manage_sheet_tabsA | Rename, delete, or duplicate a sheet tab inside a spreadsheet. Single entrypoint for the three most common tab lifecycle operations.
To CREATE a new tab from scratch, use Requires OAuth scope: |
| list_spreadsheet_commentsC | List all comments from a Google Spreadsheet. |
| manage_spreadsheet_commentA | Manage comments on a Google Spreadsheet. Actions:
|
| list_spacesA | List Google Chat spaces (rooms and direct messages) the authenticated user is a member of. Use this to discover the Requires OAuth scope:
|
| get_messagesA | List messages in a Google Chat space with sender names resolved. Use this to read a room/DM's recent messages. For text search across spaces use search_messages. For sending messages use send_message. For attachment downloads use download_chat_attachment. Senders are resolved to display names via the People API (both chat.read and contacts.readonly OAuth scopes required). |
| send_messageA | Post a text message to a Google Chat space (optionally threaded). Side effects: creates a new visible message in the space. For adding an emoji reaction to an existing message use create_reaction. For listing what's in a space use get_messages. Requires the chat.messages.create (chat_write) OAuth scope. |
| search_messagesA | Search Chat messages across one or many spaces by text and/or time. The Chat API does not support server-side full-text search, so this tool fetches messages per space (with optional createTime filter applied server-side) and does a case-insensitive substring match on message text client-side. For a single space list without filtering use get_messages. Requires both chat.read and contacts.readonly OAuth scopes (senders are resolved to names via People API). |
| create_reactionA | Add an emoji reaction to a Chat message. Side effects: creates a reaction visible to everyone in the space. Custom Workspace emoji are not supported here (Unicode only). For posting a new message use send_message. Requires the chat_write OAuth scope. |
| download_chat_attachmentA | Download a Chat message attachment to disk or expose via URL. Side effects: writes a file to the configured attachment storage (stdio mode) or publishes a 1-hour download URL (HTTP mode). In stateless mode, returns a base64 preview. Use get_messages to discover the message ID and per-message attachment indices. Requires the chat_read OAuth scope. |
| create_formA | Create a new Google Form with title and optional description. Side effects: creates a new empty form owned by the user. To add questions/items afterward use batch_update_form with createItem requests; inspect the form with get_form. Requires the forms OAuth scope. |
| get_formA | Fetch a Google Form's metadata and full item list (questions, sections, grids, media items) by its form ID. Use this before editing a form with Requires OAuth scope: |
| set_publish_settingsA | Update a Google Form's publishing and auth requirements. Side effects: mutates publish settings — changes how the form is discoverable (template) and who can submit (auth required). Does NOT change which items are on the form; for that use batch_update_form. Requires the forms OAuth scope. |
| get_form_responseA | Fetch a single submitted response to a Google Form, including all answers keyed by question ID. Use this when you already know the specific Requires OAuth scope: |
| list_form_responsesA | List submitted responses for a Google Form with basic metadata (response IDs, timestamps, answer counts). Paginated. Use this to discover response IDs and submission times, then call
Requires OAuth scope: |
| batch_update_formA | Apply a batch of Forms API edit requests in one atomic call. Primary way to modify a form after creation — add/update/delete questions, reorder items, update info, toggle quiz mode, etc. All requests apply atomically: partial failure rolls the whole batch back. Use get_form first to discover existing itemIds/questionIds. For publish settings use set_publish_settings. Requires the forms OAuth scope. |
| create_presentationA | Create a new empty Google Slides presentation. Side effects: creates a new Slides file owned by the user in My Drive root. The new deck contains one default blank slide. To add more slides use batch_update_presentation with createSlide; to duplicate an existing deck use copy_drive_file. Requires the presentations OAuth scope. |
| get_presentationA | Retrieve a presentation's structure and extract text per slide. Returns slide objectIds needed by other tools (get_page, format_slides_text, format_slides_paragraph, insert_slides_image, etc.). For a single-slide deep dive use get_page. For a rendered thumbnail image use get_page_thumbnail. Requires the presentations.readonly OAuth scope. |
| batch_update_presentationA | Apply a batch of Slides API edit requests in one atomic call. This is the low-level escape hatch for anything not covered by the high-level helpers (create_slides_shape, create_slides_text_box, format_slides_text, duplicate_slide, reorder_slides, etc.). All requests in a single call apply atomically — partial failure rolls back the whole batch. Requires the presentations OAuth scope. |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
No prompts | |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
No resources | |
Latest Blog Posts
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/HuntsDesk/ve-gws'
If you have feedback or need assistance with the MCP directory API, please join our Discord server