Skip to main content
Glama

Server Configuration

Describes the environment variables required to run the server.

NameRequiredDescriptionDefault
ALLOWED_FILE_DIRSNoColon-separated allowlist for local file reads
USER_GOOGLE_EMAILNoDefault email for single-user auth
WORKSPACE_MCP_URLNoRemote MCP endpoint URL for CLI
GOOGLE_PSE_API_KEYNoAPI key for Programmable Search Engine
MCP_ENABLE_OAUTH21No'true' to enable OAuth 2.1 multi-user support
WORKSPACE_MCP_HOSTNoBind host — default '0.0.0.0'
WORKSPACE_MCP_PORTNoListening port — default '8000'
GOOGLE_PSE_ENGINE_IDNoSearch Engine ID for PSE
OAUTH_ALLOWED_ORIGINSNoComma-separated additional CORS origins
GOOGLE_OAUTH_CLIENT_IDYesOAuth client ID from Google Cloud
WORKSPACE_EXTERNAL_URLNoExternal URL for reverse proxy setups
WORKSPACE_MCP_BASE_URINoBase server URI (no port) — default 'http://localhost'
WORKSPACE_ATTACHMENT_DIRNoDownloaded attachments dir — default '~/.workspace-mcp/attachments/'
EXTERNAL_OAUTH21_PROVIDERNo'true' for external OAuth flow with bearer tokens
GOOGLE_CLIENT_SECRET_PATHNoCustom path to 'client_secret.json'
GOOGLE_OAUTH_REDIRECT_URINoOverride OAuth callback URL — default auto-constructed
GOOGLE_MCP_CREDENTIALS_DIRNoCredential directory — default '~/.google_workspace_mcp/credentials'
GOOGLE_OAUTH_CLIENT_SECRETNoOAuth client secret for confidential clients; optional for public OAuth 2.1 PKCE clients
OAUTH_CUSTOM_REDIRECT_URISNoComma-separated additional redirect URIs
OAUTHLIB_INSECURE_TRANSPORTNoSet to '1' for development — allows 'http://' redirect
WORKSPACE_MCP_STATELESS_MODENo'true' for stateless container-friendly operation
GOOGLE_SERVICE_ACCOUNT_KEY_FILENoPath to service account JSON key file (domain-wide delegation)
GOOGLE_SERVICE_ACCOUNT_KEY_JSONNoInline service account JSON key (alternative to file)
WORKSPACE_MCP_OAUTH_PROXY_STORAGE_BACKENDNo'memory', 'disk', or 'valkey' — see storage backends
FASTMCP_SERVER_AUTH_GOOGLE_JWT_SIGNING_KEYNoCustom 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

CapabilityDetails
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

NameDescription
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:

  1. You need to re-authenticate with different credentials

  2. You want to proactively authenticate before using other tools

  3. The automatic authentication flow failed and you need to retry

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 fullText contains '...'; structured Drive queries pass through as-is. For listing a single folder by parent use list_drive_items. For file content use get_drive_file_content. Requires the drive.readonly OAuth scope.

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 keepForever. Use this to discover revision IDs before calling restore_drive_revision, or to audit who changed what.

Requires OAuth scope: https://www.googleapis.com/auth/drive.readonly (or broader). Read-only.

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 (keepForever: true).

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: https://www.googleapis.com/auth/drive (write). Large files (>100 MB) may take several seconds due to download+upload cycle.

Limitation: Google-native files (Docs, Sheets, Slides — MIME type application/vnd.google-apps.*) do NOT expose raw revision content via the Drive API. Attempting to restore a native file returns an explanatory error. For those, open the file in Google Docs/Sheets/Slides and use the built-in "Version history" UI (File > Version history > See version history). Binary-content files (PDFs, DOCX, XLSX, images, ZIP, etc.) are fully supported.

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 files.list query with name contains '<query>' and a mimeType filter pinned to native Google Docs. It does NOT search document content; for full-text search use search_drive_files with a fullText query, or an external search index. For listing docs in a specific folder, use list_docs_in_folder.

Requires OAuth scope: https://www.googleapis.com/auth/drive.readonly (or broader drive scope). trashed=false is always applied — trashed docs are excluded.

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 application/vnd.google-apps.document) that live directly inside a given Drive folder.

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 search_docs. For non-Doc files (Sheets, Slides, PDFs, etc.) in the folder, use list_drive_items or search_drive_files.

Only direct children are returned — subfolders are NOT recursed. Shared drives are supported via supportsAllDrives=True + includeItemsFromAllDrives=True. Trashed docs are excluded.

Requires OAuth scope: https://www.googleapis.com/auth/drive.readonly (or broader drive 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 text as markdown and insert it with native Docs formatting (headings, bold, italic, bullets, numbered lists). Works for both plain insertion and range replacement. When enabled, explicit formatting parameters (bold, italic, font_size, etc.) must NOT be set — markdown brings its own formatting.

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:

  • Replace placeholder text (e.g., {{TITLE}}) with real content

  • Update specific words or phrases throughout the document

  • Make targeted text changes without risk of index errors

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:

  • If the header/footer does not exist, it is automatically created first.

  • If the header/footer already exists, its content is replaced.

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:

  • Finding the correct index for table insertion

  • Understanding document layout before making changes

  • Locating existing tables and their positions

  • Getting document statistics and complexity info

  • Inspecting structure of specific tabs

CRITICAL FOR TABLE OPERATIONS: ALWAYS call this BEFORE creating tables to get a safe insertion index.

WHAT THE OUTPUT SHOWS:

  • total_elements: Number of document elements

  • total_length: Maximum safe index for insertion

  • tables: Number of existing tables

  • table_details: Position and dimensions of each table

  • headers / footers: Real segment IDs and previews for header/footer editing

  • tabs: List of available tabs in the document (if no tab_id specified)

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:

  • NEVER use index values like 1, 2, 10 without calling inspect_doc_structure first

  • ALWAYS get index from inspect_doc_structure 'total_length' field

  • Index must be a valid insertion point in the document

DATA FORMAT REQUIREMENTS:

  • Must be 2D list of strings only

  • Each inner list = one table row

  • All rows MUST have same number of columns

  • Use empty strings "" for empty cells, never None

  • Use debug_table_structure after creation to verify results

debug_table_structureA

ESSENTIAL DEBUGGING TOOL - Use this whenever tables don't work as expected.

USE THIS IMMEDIATELY WHEN:

  • Table population put data in wrong cells

  • You get "table not found" errors

  • Data appears concatenated in first cell

  • Need to understand existing table structure

  • Planning to use populate_existing_table

WHAT THIS SHOWS YOU:

  • Exact table dimensions (rows × columns)

  • Each cell's position coordinates (row,col)

  • Current content in each cell

  • Insertion indices for each cell

  • Table boundaries and ranges

HOW TO READ THE OUTPUT:

  • "dimensions": "2x3" = 2 rows, 3 columns

  • "position": "(0,0)" = first row, first column

  • "current_content": What's actually in each cell right now

  • "insertion_index": Where new text would be inserted in that cell

WORKFLOW INTEGRATION:

  1. After creating table → Use this to verify structure

  2. Before populating → Use this to plan your data format

  3. After population fails → Use this to see what went wrong

  4. When debugging → Compare your data array to actual table structure

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 tab_id to target a specific tab — call this first to discover IDs, titles, and the tab hierarchy. Returned tabs preserve document order; indentation in the output indicates nesting depth (child tabs shown under their parent).

Requires OAuth scope: https://www.googleapis.com/auth/documents.readonly (or broader). Read-only.

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 # H1..### H3, **bold**, *italic*, - bullets, 1. numbered, and - [ ] checkbox (plus - [x]). Requires the documents OAuth scope.

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 = mailto:<email>). When Google Docs renders the document, that linked-email pattern is auto-converted into a rich person chip — a small inline pill showing the person's name, avatar, and hover card. The chip is a "smart chip" and shows up in get_doc_smart_chips as type person.

Requires OAuth scope: https://www.googleapis.com/auth/documents (write). For a Drive-file chip instead, use insert_doc_file_chip. For a plain hyperlink, use insert_doc_link.

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 person and richLink inline elements, and returns their type, character range, and key properties. Useful for auditing @mentions (who is referenced where), validating links to external resources, or building a chip inventory before batch-editing. Does NOT include inline hyperlinks that never upgraded to chips (use a direct text scan for those).

Requires OAuth scope: https://www.googleapis.com/auth/documents.readonly (or broader). Read-only — safe to call repeatedly.

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 insert_doc_person_chip or insert_doc_file_chip won't show up in this result until a user opens the doc in the Docs UI and Docs upgrades the raw linked text into a chip.

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:

  • create: Create a new document-level comment. Requires comment_content. Note: The Drive API cannot anchor comments to specific text; only the Google Docs UI can do that.

  • reply: Reply to a comment. Requires comment_id and comment_content.

  • resolve: Resolve a comment. Requires comment_id.

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., =SUM(TaxRate) instead of =SUM(Config!B2:B2). Named ranges show up in the Data > Named ranges sidebar and in formula autocomplete. Makes formulas more readable and lets you move the underlying cells without breaking references. To use the named range, write it bare in a formula (=TaxRate) — no quotes, no sheet prefix.

Requires OAuth scope: https://www.googleapis.com/auth/spreadsheets (write).

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: https://www.googleapis.com/auth/spreadsheets (write). Protection does NOT prevent the owner or anyone with file-level "Editor" permission on the Drive file from bypassing via the Sheets UI — it only gates in-cell edits. For hard access control, use Drive sharing.

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 create_sheet (separate tool). To reorder tabs, use batch_update with updateSheetProperties.index. Deletion is permanent — the undo is only available through the Sheets UI, not via the API.

Requires OAuth scope: https://www.googleapis.com/auth/spreadsheets (write).

list_spreadsheet_commentsC

List all comments from a Google Spreadsheet.

manage_spreadsheet_commentA

Manage comments on a Google Spreadsheet.

Actions:

  • create: Create a new comment. Requires comment_content. Note: The Drive API cannot anchor comments to arbitrary text; Sheets comments are cell-scoped via the API.

  • reply: Reply to a comment. Requires comment_id and comment_content.

  • resolve: Resolve a comment. Requires comment_id.

list_spacesA

List Google Chat spaces (rooms and direct messages) the authenticated user is a member of.

Use this to discover the space_id (in spaces/<id> format) needed for get_messages, send_message, and related Chat tools. The user only sees spaces they have joined — this will not surface public spaces in the workspace they haven't joined.

Requires OAuth scope: https://www.googleapis.com/auth/chat.spaces.readonly (read-only).

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 batch_update_form — the returned item indices and itemId/questionId values are the handles you pass into update/delete requests. For response data (submitted answers), use list_form_responses or get_form_response instead.

Requires OAuth scope: https://www.googleapis.com/auth/forms.body or forms.body.readonly (read-only).

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 responseId (e.g., from a prior list_form_responses call or from a webhook/trigger). For bulk listing of all responses on a form, use list_form_responses. To look up which questionId maps to which question prompt, call get_form and read the item list.

Requires OAuth scope: https://www.googleapis.com/auth/forms.responses.readonly.

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 get_form_response with a specific responseId to pull the full answer payload. For the form's structure (questions, options), use get_form.

Requires OAuth scope: https://www.googleapis.com/auth/forms.responses.readonly.

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

NameDescription

No prompts

Resources

Contextual data attached and managed by the client

NameDescription

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