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 | Searches messages in a user's Gmail account based on a query. Returns both Message IDs and Thread IDs for each found message, along with Gmail web interface links for manual verification. Supports pagination via page_token parameter. |
| get_gmail_message_contentB | Retrieves the full content (subject, sender, recipients, body) of a specific Gmail message. |
| get_gmail_messages_content_batchA | Retrieves the content of multiple Gmail messages in a single batch request. Supports up to 25 messages per batch to prevent SSL connection exhaustion. |
| get_gmail_attachment_contentA | Downloads an email attachment and saves it to local disk. In stdio mode, returns the local file path for direct access. In HTTP mode, returns a temporary download URL (valid for 1 hour). May re-fetch message metadata to resolve filename and MIME type. |
| send_gmail_messageB | 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 | Retrieves the complete content of a Gmail conversation thread, including all messages. |
| get_gmail_threads_content_batchA | Retrieves the content of multiple Gmail threads in a single batch request. Supports up to 25 threads per batch to prevent SSL connection exhaustion. |
| list_gmail_labelsB | Lists all labels in the user's Gmail account. |
| manage_gmail_labelB | Manages Gmail labels: create, update, or delete labels. |
| list_gmail_filtersB | Lists all Gmail filters configured in the user's mailbox. |
| manage_gmail_filterB | Manages Gmail filters. Supports creating and deleting filters. |
| modify_gmail_message_labelsA | Adds or removes labels from a Gmail message. To archive an email, remove the INBOX label. To delete an email, add the TRASH label. |
| batch_modify_gmail_message_labelsB | Adds or removes labels from multiple Gmail messages in a single batch request. |
| search_drive_filesB | Searches for files and folders within a user's Google Drive, including shared drives. |
| get_drive_file_contentA | Retrieves the content of a specific Google Drive file by ID, supporting files in shared drives. • Native Google Docs, Sheets, Slides → exported as text / CSV. • Office files (.docx, .xlsx, .pptx) → unzipped & parsed with std-lib to extract readable text. • PDFs → text extracted with pypdf when possible; scanned/image-only PDFs fall back to a download hint. • Images → returned as base64 with MIME metadata for multimodal clients. • Any other file → downloaded; tries UTF-8 decode, else notes binary. |
| get_drive_file_download_urlA | Downloads a Google Drive file and saves it to local disk. In stdio mode, returns the local file path for direct access. In HTTP mode, returns a temporary download URL (valid for 1 hour). For Google native files (Docs, Sheets, Slides), exports to a useful format:
For other files, downloads the original file format. |
| list_drive_itemsA | Lists files and folders, supporting shared drives.
If |
| create_drive_folderB | Creates a new folder in Google Drive, supporting creation within shared drives. |
| create_drive_fileB | Creates a new file in Google Drive, supporting creation within shared drives. Accepts either direct content or a fileUrl to fetch the content from. |
| import_to_google_docB | Imports a file (Markdown, DOCX, TXT, HTML, RTF, ODT) into Google Docs format with automatic conversion. Google Drive automatically converts the source file to native Google Docs format, preserving formatting like headings, lists, bold, italic, etc. |
| get_drive_file_permissionsB | Gets detailed metadata about a Google Drive file including sharing permissions. |
| check_drive_file_public_accessB | Searches for a file by name and checks if it has public link sharing enabled. |
| update_drive_fileB | Updates metadata and properties of a Google Drive file. |
| get_drive_shareable_linkB | Gets the shareable link for a Google Drive file or folder. |
| manage_drive_accessB | Consolidated tool for managing Google Drive file and folder access permissions. Supports granting, batch-granting, updating, revoking permissions, and transferring file ownership -- all through a single entry point. |
| copy_drive_fileC | Creates a copy of an existing Google Drive file. This tool copies the template document to a new location with an optional new name. The copy maintains all formatting and content from the original file. |
| set_drive_file_permissionsA | Sets file-level sharing settings and controls link sharing for a Google Drive file or folder. This is a high-level tool for the most common permission changes. Use this to toggle "anyone with the link" access or configure file-level sharing behavior. For managing individual user/group permissions, use share_drive_file or update_drive_permission instead. |
| 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 revision history for a Drive file. Returns each revision's ID, modified time, last-modifying user, and size (when available). Useful before calling restore_drive_revision. |
| restore_drive_revisionA | Restore a Drive file to a previous revision. Downloads the revision's raw content and re-uploads it as the current version. Works for binary file types (PDFs, DOCX, images, etc.). Google-native files (Docs, Sheets, Slides) do not expose raw revision content via the API — for those, use the Google Docs "Version history" UI instead. |
| list_calendarsB | Retrieves a list of calendars accessible to the authenticated user. |
| get_eventsA | Retrieves events from a specified Google Calendar. Can retrieve a single event by ID or multiple events within a time range. You can also search for events by keyword by supplying the optional "query" param. |
| manage_eventC | Manages calendar events. Supports creating, updating, deleting, and RSVP. |
| manage_out_of_officeC | Manages Out of Office events on Google Calendar. These special events auto-decline meeting invitations and set the user's status to "Out of office" across Google Workspace. |
| manage_focus_timeA | Manages Focus Time events on Google Calendar. These special events auto-decline meeting invitations and, by default, set the user's chat status to Do Not Disturb, helping protect blocks of uninterrupted work time. |
| query_freebusyB | Returns free/busy information for a set of calendars. |
| create_calendarB | Creates a new secondary Google Calendar. |
| search_docsC | Searches for Google Docs by name using Drive API (mimeType filter). Returns: str: A formatted list of Google Docs matching the search query. |
| get_doc_contentA | Retrieves content of a Google Doc or a Drive file (like .docx) identified by document_id.
|
| list_docs_in_folderC | Lists Google Docs within a specific Drive folder. Returns: str: A formatted list of Google Docs in the specified folder. |
| 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_elementsC | Inserts structural elements like tables, lists, or page breaks into a Google Doc. |
| insert_doc_imageB | Inserts an image into a Google Doc from Drive or a URL. |
| 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_infoA | 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_pdfB | Exports a Google Doc to PDF format and saves it to Google Drive. |
| update_paragraph_styleA | 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_tabB | Inserts a new tab into a Google Doc. |
| delete_doc_tabB | Deletes a tab from a Google Doc by its tab ID. |
| update_doc_tabB | Renames a tab in a Google Doc. |
| list_doc_tabsA | List all tabs in a Google Doc, including nested child tabs. Returns a flattened hierarchy with tab IDs, titles, index positions, and
nesting depth. Useful as a prerequisite for any tool that takes a |
| insert_doc_markdownA | Insert markdown content into a Google Doc with native formatting applied. Supports |
| insert_doc_linkB | Insert clickable linked text at a specified index in a document. |
| insert_doc_person_chipB | Insert an @mention person chip at a specified index. The person's email is inserted as text with a |
| insert_doc_file_chipC | Insert a Drive file smart chip at the specified index. A Drive file URL inserted as linked text auto-converts into a file chip in Google Docs, showing the file's name, icon, and preview. |
| get_doc_smart_chipsA | Extract all smart chips (person mentions, file/rich links) from a document. Walks the document body and returns each chip's type, position, and properties. |
| 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_spreadsheetsB | Lists spreadsheets from Google Drive that the user has access to. |
| get_spreadsheet_infoB | Gets information about a specific spreadsheet including its sheets. |
| read_sheet_valuesB | Reads values from a specific range in a Google Sheet. |
| modify_sheet_valuesB | Modifies values in a specific range of a Google Sheet - can write, update, or clear values. |
| format_sheet_rangeC | 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_formattingC | Manages conditional formatting rules on a Google Sheet. Supports adding, updating, and deleting conditional formatting rules via a single tool. |
| create_spreadsheetB | Creates a new Google Spreadsheet. |
| create_sheetB | Creates a new sheet within an existing spreadsheet. |
| list_sheet_tablesA | Lists all structured tables in a spreadsheet with their IDs, names, ranges, and column details. Use this to find table IDs for append_table_rows. |
| append_table_rowsA | Appends rows to a structured table in a Google Sheet. The rows are added to the end of the table body, automatically extending the table range. Use list_sheet_tables first to find the table ID. |
| resize_sheet_dimensionsB | 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_validationB | Add data validation rules to a cell range (dropdowns, number bounds, custom formulas). |
| add_sheet_named_rangeB | Create a named range that can be referenced by formulas. |
| protect_sheet_rangeB | Protect a range so that only specified editors can modify it. |
| manage_sheet_tabsB | Rename, delete, or duplicate a sheet tab within a spreadsheet. |
| list_spreadsheet_commentsC | List all comments from a Google Spreadsheet. |
| manage_spreadsheet_commentA | Manage comments on a Google Spreadsheet. Actions:
|
| list_spacesC | Lists Google Chat spaces (rooms and direct messages) accessible to the user. Returns: str: A formatted list of Google Chat spaces accessible to the user. |
| get_messagesC | Retrieves messages from a Google Chat space. |
| send_messageB | Sends a message to a Google Chat space. |
| search_messagesB | Searches for messages in Google Chat spaces by text content and/or time range. |
| create_reactionB | Adds an emoji reaction to a Google Chat message. |
| download_chat_attachmentA | Downloads an attachment from a Google Chat message and saves it to local disk. In stdio mode, returns the local file path for direct access. In HTTP mode, returns a temporary download URL (valid for 1 hour). |
| create_formC | Create a new form using the title given in the provided form message in the request. |
| get_formC | Get a form. |
| set_publish_settingsB | Updates the publish settings of a form. |
| get_form_responseC | Get one response from the form. |
| list_form_responsesC | List a form's responses. |
| batch_update_formA | Apply batch updates to a Google Form. Supports adding, updating, and deleting form items, as well as updating form metadata and settings. This is the primary method for modifying form content after creation. |
| create_presentationB | Create a new Google Slides presentation. |
| get_presentationB | Get details about a Google Slides presentation. |
| batch_update_presentationB | Apply batch updates to a Google Slides presentation. |
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