io.github.taylorwilsdon/workspace-mcp
PYPI · WORKSPACE-MCP · SCANNED SEP 20
Google Workspace MCP server for Gmail, Drive, Calendar, Docs, Sheets, Slides, Forms, Tasks, Chat.
Available components
How this component scores in each security and reliability category. Every signal is checked automatically from public evidence about the published package, including repeated runs of it in an isolated sandbox, and we only credit what we can confirm. How we score → Why this is hard to score →
Supply Chain Security50
- Malware scan not yet available for this package.Unverified
- No known CVEs affecting this package version or its production dependencies.Pass
- Runs setuptools.build_meta at install time, a recognised native-build step with no shell scripting around it. View diagnostics → Pass
- 4 of 58 dependencies flagged as unhealthy. View diagnostics → Partial
Provenance & Transparency10
- Repository check failed: no source repository is declared. See how to fix → View diagnostics → Fail
- Provenance check failed: no build-provenance attestation is published. See how to fix → View diagnostics → Fail
- License check failed: no license is declared. See how to fix → Fail
- Actively maintained (last published 1 days ago).Pass
- Publishes a security disclosure policy (SECURITY.md).Pass
Schema Quality & AI Usability64
- AI-judged instruction clarity (excellent).Pass
- Context-footprint check failed: tool/resource definitions use about 26154 tokens (~212/item across 123 items; 123 tools + 0 resources), over budget; trim descriptions and params. See how to fix → Fail
- Usage-examples check failed: none of the tools include examples. See how to fix → Fail
Stability & Change Management83
- Stability observed for 25 of 30 days with no destabilising changes; credit accrues until the full window elapses.Partial
Tool Coverage98
- 99% of tools have a non-trivial description (not blank, and not just the tool's name).Partial
- 93% of tool parameters carry a description.Partial
- Structured output schemas are declared (100% of tools); any adoption earns full credit.Pass
Tool Safety100
- No prompt-injection markers were found in the server instructions, tool names or descriptions we captured.Pass
- All 6 tool(s) whose name or description implies an irreversible operation declare an MCP destructiveHint annotation.Pass
- An AI judge read all 123 captured unit(s) of tool text and found none that tries to manipulate the model reading it.Pass
Capabilities100
- Implements a current MCP spec version (2026-07-28).Pass
How do I install the io.github.taylorwilsdon/workspace-mcp server?
io.github.taylorwilsdon/workspace-mcp runs locally as a PyPI package, launched with uvx workspace-mcp. Ready-made configuration for Claude, Cursor, VS Code, Codex and 5 more is on this page, copied from each client's own documentation.
pypi · workspace-mcp
claude mcp add taylorwilsdon-workspace-mcp -- uvx workspace-mcp
{
"mcpServers": {
"taylorwilsdon-workspace-mcp": {
"command": "uvx",
"args": [
"workspace-mcp"
]
}
}
} {
"servers": {
"taylorwilsdon-workspace-mcp": {
"command": "uvx",
"args": [
"workspace-mcp"
]
}
}
} codex mcp add taylorwilsdon-workspace-mcp -- uvx workspace-mcp
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"taylorwilsdon-workspace-mcp": {
"type": "local",
"command": [
"uvx",
"workspace-mcp"
],
"enabled": true
}
}
} openclaw mcp add taylorwilsdon-workspace-mcp --command uvx --arg workspace-mcp
mcp_servers:
taylorwilsdon-workspace-mcp:
command: "uvx"
args: ["workspace-mcp"] {
"McpServers": {
"taylorwilsdon-workspace-mcp": {
"Transport": "stdio",
"Command": "uvx",
"Arguments": [
"workspace-mcp"
]
}
}
} assistant mcp add taylorwilsdon-workspace-mcp -t stdio -c uvx -a workspace-mcp
{
"mcpServers": {
"taylorwilsdon-workspace-mcp": {
"command": "uvx",
"args": [
"workspace-mcp"
]
}
}
} Every change we have recorded for this component, newest first. Security-relevant changes are always shown. ▲ marks a change for the better, ▼ a change for the worse; unmarked changes are neutral.
- 19 Sept 26 +1
No change was recorded against any check on this day. Stability & Change Management went from 77 to 80. That category is still filling its 30-day observation window: 23 days of observed history at the previous scan, 24 at this one. The score rises as the window fills, whether or not the server changes.
- 18 Sept 26 −18
- Malware scan: pass → unverified ▼ security
- Stability: pass → 0.77 functional
- 17 Sept 26 0
- Stability: 0.97 → unverified ▼ security
- Tool safety: pass → unverified ▼ security
- Malware scan: pass → unverified ▼ security
- Stability: 0.97 → pass security
- Schema quality: 191 → 212 ▼ functional
- Capabilities: pass → unverified ▼ functional
- Tool coverage: 99 → unverified ▼ functional
- Schema quality: Schema quality not yet verified: we do not have a sandbox capture of the MCP schema this version of the package serves yet. functional
- Package version: 1.25.0 → 1.27.0 functional
- 16 Sept 26 +15
- Malware scan: unverified → pass ▲ security
- 15 Sept 26 −14
- Malware scan: pass → unverified ▼ security
- 14 Sept 26 +15
- Malware scan: unverified → pass ▲ security
- 13 Sept 26 −2
- Stability: pass → 0.87 functional
- 12 Sept 26 +1
- Stability: 0.97 → pass security
Diagnostic detail from the automated scan of this channel: what the scanner observed at each step, so you can see exactly where a check passed or failed. It is informational only and never changes the trust score.
Captured 20 Sept 2026 · Analysed pypi/workspace-mcp@1.27.0
Provenance No attestation
The registry publishes no build provenance for this version, so there is nothing to verify.
| Result | No attestation |
|---|---|
| Ecosystem | pypi |
Background: How many MCP packages publish verified provenance →
Install scripts 1 script
| Hook | Tier | Command |
|---|---|---|
| build_backend | allowlisted | setuptools.build_meta |
Background: Why install scripts are a supply-chain risk →
Dependencies 58 packages
| Packages resolved | 58 |
|---|---|
| Stale | 3 |
| No linked repository | 1 |
| Tree resolution | Complete |
Background: SBOMs and build attestations, explained →
The tools this component advertises to a client, with an estimated token cost for each. Expand a tool to see its parameters and schema. The per-tool counts are indicative and are not scored directly; the schema's total context footprint is one signal in Schema Quality & AI Usability. A tool's description is untrusted text the model reads on every call, which is what makes this list a security surface and not just an inventory: how tool poisoning works →
append_table_rows Append Table Rows ~138
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.
| Name | Type | Req | Description |
|---|---|---|---|
| spreadsheet_id | string | yes | The ID of the spreadsheet. Required. |
| table_id | string | yes | The ID of the table to append to (get from list_sheet_tables). Required. |
| user_google_email | string | yes | The user's Google email address. Required. |
| values | – | yes | 2D array of values to append. Each inner list is one row. Can be a JSON string or Python list. Required. |
| Name | Type | Req | Description |
|---|---|---|---|
| result | string | yes | – |
No examples provided.
batch_modify_gmail_message_labels Batch Modify Gmail Message Labels ~187
Adds or removes labels from multiple Gmail messages in a single batch request. Takes MESSAGE ids, not thread ids. Gmail's batch endpoint returns no per-message result and silently ignores ids it does not recognise, so by default this reads the messages back afterwards and reports which ids actually changed.
| Name | Type | Req | Description |
|---|---|---|---|
| add_label_ids | array | – | List of label IDs to add to the messages. |
| message_ids | array | yes | A list of message IDs to modify. |
| remove_label_ids | array | – | List of label IDs to remove from the messages. |
| user_google_email | string | yes | The user's Google email address. Required. |
| verify | boolean | – | Read the messages back and report per-id outcomes. Costs one extra (batched) read per id. Set False for very large sweeps where that cost matters and an unverified result is acceptable. |
| Name | Type | Req | Description |
|---|---|---|---|
| result | string | yes | – |
No examples provided.
batch_update_doc Batch Update Doc ~384
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.
| Name | Type | Req | Description |
|---|---|---|---|
| document_id | string | yes | ID of the document to update |
| operations | array | yes | List of operation dicts. Each operation MUST have a 'type' field. All operations accept an optional 'tab_id' to target a specific tab. |
| user_google_email | string | yes | User's Google email address |
| Name | Type | Req | Description |
|---|---|---|---|
| result | string | yes | – |
No examples provided.
batch_update_form Batch Update Form ~161
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.
| Name | Type | Req | Description |
|---|---|---|---|
| form_id | string | yes | The ID of the form to update. |
| requests | array | yes | List of update requests to apply. Supported request types: - createItem: Add a new question or content item - updateItem: Modify an existing item - deleteItem: Remove an item - moveItem: Reorder an i… |
| user_google_email | string | yes | The user's Google email address. Required. |
| Name | Type | Req | Description |
|---|---|---|---|
| result | string | yes | – |
No examples provided.
batch_update_presentation Batch Update Presentation ~63
Apply batch updates to a Google Slides presentation.
| Name | Type | Req | Description |
|---|---|---|---|
| presentation_id | string | yes | The ID of the presentation to update. |
| requests | array | yes | List of update requests to apply. |
| user_google_email | string | yes | The user's Google email address. Required. |
| Name | Type | Req | Description |
|---|---|---|---|
| result | string | yes | – |
No examples provided.
check_drive_file_public_access Check Drive File Public Access ~130
Searches for a file by name and checks if it has public link sharing enabled.
| Name | Type | Req | Description |
|---|---|---|---|
| drive_id | – | – | ID of the shared drive to scope the search to. When set, the underlying files.list call uses corpora='drive' and the given driveId, which is required to re… |
| file_name | string | yes | The name of the file to check. |
| user_google_email | string | yes | The user's Google email address. Required. |
| Name | Type | Req | Description |
|---|---|---|---|
| result | string | yes | – |
No examples provided.
copy_drive_file Copy Drive File ~134
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.
| Name | Type | Req | Description |
|---|---|---|---|
| file_id | string | yes | The ID of the file to copy. Required. |
| new_name | – | – | New name for the copied file. If not provided, uses "Copy of [original name]". |
| parent_folder_id | string | – | The ID of the folder where the copy should be created. Defaults to 'root' (My Drive). |
| user_google_email | string | yes | The user's Google email address. Required. |
| Name | Type | Req | Description |
|---|---|---|---|
| result | string | yes | – |
No examples provided.
create_calendar Create Calendar ~76
Creates a new secondary Google Calendar.
| Name | Type | Req | Description |
|---|---|---|---|
| description | – | – | An optional description for the calendar. |
| summary | string | yes | The title/name of the new calendar. |
| timezone | – | – | IANA timezone for the calendar (e.g. 'America/New_York'). |
| user_google_email | string | yes | The user's Google email address. Required. |
| Name | Type | Req | Description |
|---|---|---|---|
| result | string | yes | – |
No examples provided.
create_doc Create Doc ~149
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.
| Name | Type | Req | Description |
|---|---|---|---|
| content | string | – | Optional initial plain text content to insert |
| title | string | yes | Title of the new document |
| user_google_email | string | yes | User's Google email address |
| Name | Type | Req | Description |
|---|---|---|---|
| result | string | yes | – |
No examples provided.
create_drive_file Create Drive File ~255
Creates a new file in Google Drive, supporting creation within shared drives. Accepts direct text content, inline base64 bytes, or a fileUrl to fetch content from. This stores the supplied bytes without converting them to Google Docs, Sheets, or Slides. Use the matching import_to_google_* tool for Google-native conversion.
| Name | Type | Req | Description |
|---|---|---|---|
| base64_content | – | – | Standard base64-encoded file bytes. |
| base64_sha256 | – | – | Expected SHA-256 of decoded base64_content. Recommended for binary payload integrity checks. |
| content | – | – | If provided, the content to write to the file. |
| content_mime_type | – | – | MIME type for base64_content uploads. |
| fileUrl | – | – | If provided, fetches the file content from this URL. Supports file://, http://, and https:// protocols. |
| file_name | string | yes | The name for the new file. |
| folder_id | string | – | The ID of the parent folder. Defaults to 'root'. For shared drives, this must be a folder ID within the shared drive. |
| mime_type | string | – | The MIME type of the file. Defaults to 'text/plain'. |
| user_google_email | string | yes | The user's Google email address. Required. |
| Name | Type | Req | Description |
|---|---|---|---|
| result | string | yes | – |
No examples provided.
create_drive_folder Create Drive Folder ~86
Creates a new folder in Google Drive, supporting creation within shared drives.
| Name | Type | Req | Description |
|---|---|---|---|
| folder_name | string | yes | The name for the new folder. |
| parent_folder_id | string | – | The ID of the parent folder. Defaults to 'root'. For shared drives, use a folder ID within that shared drive. |
| user_google_email | string | yes | The user's Google email address. Required. |
| Name | Type | Req | Description |
|---|---|---|---|
| result | string | yes | – |
No examples provided.
create_form Create Form ~77
Create a new form using the title given in the provided form message in the request.
| Name | Type | Req | Description |
|---|---|---|---|
| description | – | – | The description of the form. |
| document_title | – | – | The document title (shown in browser tab). |
| title | string | yes | The title of the form. |
| user_google_email | string | yes | The user's Google email address. Required. |
| Name | Type | Req | Description |
|---|---|---|---|
| result | string | yes | – |
No examples provided.
create_presentation Create Presentation ~52
Create a new Google Slides presentation.
| Name | Type | Req | Description |
|---|---|---|---|
| title | string | – | The title for the new presentation. Defaults to "Untitled Presentation". |
| user_google_email | string | yes | The user's Google email address. Required. |
| Name | Type | Req | Description |
|---|---|---|---|
| result | string | yes | – |
No examples provided.
create_reaction Create Reaction ~67
Adds an emoji reaction to a Google Chat message.
| Name | Type | Req | Description |
|---|---|---|---|
| emoji_unicode | string | yes | The emoji character to react with (e.g. 👍). |
| message_id | string | yes | The message resource name (e.g. spaces/X/messages/Y). |
| user_google_email | string | yes | – |
| Name | Type | Req | Description |
|---|---|---|---|
| result | string | yes | – |
No examples provided.
create_script_project Create Script Project ~52
Creates a new Apps Script project.
| Name | Type | Req | Description |
|---|---|---|---|
| parent_id | – | – | Optional Drive folder ID or bound container ID |
| title | string | yes | Project title |
| user_google_email | string | yes | User's email address |
| Name | Type | Req | Description |
|---|---|---|---|
| result | string | yes | – |
No examples provided.
create_sheet Create Sheet ~95
Creates a new sheet or duplicates an existing sheet (user_google_email: str, spreadsheet_id: str, sheet_name: Optional[str] = None, source_sheet_name: Optional[str] = None, insert_sheet_index: Optional[int] = None).
| Name | Type | Req | Description |
|---|---|---|---|
| insert_sheet_index | – | – | – |
| sheet_name | – | – | – |
| source_sheet_name | – | – | – |
| spreadsheet_id | string | yes | – |
| user_google_email | string | yes | – |
| Name | Type | Req | Description |
|---|---|---|---|
| result | string | yes | – |
No examples provided.
create_spreadsheet Create Spreadsheet ~70
Creates a new Google Spreadsheet.
| Name | Type | Req | Description |
|---|---|---|---|
| sheet_names | – | – | List of sheet names to create. If not provided, creates one sheet with default name. |
| title | string | yes | The title of the new spreadsheet. Required. |
| user_google_email | string | yes | The user's Google email address. Required. |
| Name | Type | Req | Description |
|---|---|---|---|
| result | string | yes | – |
No examples provided.
create_table_with_data Create Table with Data ~485
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
| Name | Type | Req | Description |
|---|---|---|---|
| bold_headers | boolean | – | Whether to make first row bold (default: true) |
| document_id | string | yes | ID of the document to update |
| header_rows | integer | – | Number of leading rows to mark as a repeating header that reappears after each page break. Must be between 0 and the number of table rows (default: 0 = none) |
| index | integer | yes | Document position (MANDATORY: get from inspect_doc_structure 'total_length') |
| tab_id | – | – | Optional tab ID to create the table in a specific tab |
| table_data | array | yes | 2D list of strings - EXACT format: [["col1", "col2"], ["row1col1", "row1col2"]] |
| user_google_email | string | yes | User's Google email address |
| Name | Type | Req | Description |
|---|---|---|---|
| result | string | yes | – |
No examples provided.
create_version Create Version ~71
Creates a new immutable version of a script project. Versions capture a snapshot of the current script code. Once created, versions cannot be modified.
| Name | Type | Req | Description |
|---|---|---|---|
| description | – | – | Optional description for this version |
| script_id | string | yes | The script project ID |
| user_google_email | string | yes | User's email address |
| Name | Type | Req | Description |
|---|---|---|---|
| result | string | yes | – |
No examples provided.
debug_docs_runtime_info Debug Docs Runtime Info ~50
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.
| Name | Type | Req | Description |
|---|---|---|---|
| user_google_email | string | yes | – |
| Name | Type | Req | Description |
|---|---|---|---|
| result | string | yes | – |
No examples provided.
debug_table_structure Debug Table Structure ~305
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
| Name | Type | Req | Description |
|---|---|---|---|
| document_id | string | yes | ID of the document to inspect |
| table_index | integer | – | Which table to debug (0 = first table, 1 = second table, etc.) |
| user_google_email | string | yes | User's Google email address |
| Name | Type | Req | Description |
|---|---|---|---|
| result | string | yes | – |
No examples provided.
delete_script_project Delete Script Project ~55
Deletes an Apps Script project. This permanently deletes the script project. The action cannot be undone.
| Name | Type | Req | Description |
|---|---|---|---|
| script_id | string | yes | The script project ID to delete |
| user_google_email | string | yes | User's email address |
| Name | Type | Req | Description |
|---|---|---|---|
| result | string | yes | – |
No examples provided.
download_chat_attachment Download Chat Attachment ~103
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).
| Name | Type | Req | Description |
|---|---|---|---|
| attachment_index | integer | – | Zero-based index of the attachment to download (default 0). |
| message_id | string | yes | The message resource name (e.g. spaces/X/messages/Y). |
| user_google_email | string | yes | – |
| Name | Type | Req | Description |
|---|---|---|---|
| result | string | yes | – |
No examples provided.
draft_gmail_message Draft Gmail Message ~675
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. SCHEDULED SEND IS NOT AVAILABLE. Gmail's REST API exposes no send-time parameter; the Schedule send feature is web-UI only, and a message cannot be placed in the Scheduled folder through the API. Do not claim a message was scheduled. To deliver at a chosen time, create a draft with draft_gmail_message. An external scheduler must retain the message data to create and send a new message via send_gmail_message then, or call users.drafts.send with the draft ID returned by draft_gmail_message. Alternatively, let the user schedule the draft in the Gmail UI.
| Name | Type | Req | Description |
|---|---|---|---|
| attachments | – | – | Optional list of attachments. Each can have: 'url' (fetch from URL — works with MCP attachment URLs from get_drive_file_download_url / get_gmail_attachment_content), OR 'path' (file path, auto-encode… |
| bcc | – | – | Optional BCC email address. |
| body | string | yes | Email body (plain text). |
| body_format | string | – | Email body format. Use 'plain' for plaintext or 'html' for HTML content. |
| cc | – | – | Optional CC email address. |
| from_email | – | – | Optional 'Send As' alias email address. Must be configured in Gmail settings (Settings > Accounts > Send mail as). If not provided, uses the account's default Send As address, falling back to the aut… |
| from_name | – | – | Optional sender display name (e.g., 'Peter Hartree'). If provided, the From header will be formatted as 'Name <email>'. |
| in_reply_to | – | – | Optional RFC Message-ID to explicitly reply to a specific message (e.g., '<message123@gmail.com>'). Omit to reply to the latest eligible message in thread_id. |
| include_signature | boolean | – | Whether to append the Gmail signature from Settings > Signature when available. Defaults to true. |
| quote_original | boolean | – | Whether to include the original message as a quoted reply. Only has an effect when thread_id is provided. Defaults to false. |
| references | – | – | Optional Message-ID ancestry chain. Normally omit when thread_id is provided; the server derives the chain through the selected reply target. |
| subject | string | yes | Email subject. |
| thread_id | – | – | Optional Gmail thread ID to reply within. When in_reply_to is omitted, replies to the latest non-draft, non-trash message with an RFC Message-ID. |
| to | – | – | Optional recipient email address. |
| user_google_email | string | yes | The user's Google email address. Required for authentication. |
| Name | Type | Req | Description |
|---|---|---|---|
| result | string | yes | – |
No examples provided.
export_doc_to_pdf Export Doc to PDF ~105
Exports a Google Doc to PDF format and saves it to Google Drive.
| Name | Type | Req | Description |
|---|---|---|---|
| document_id | string | yes | ID of the Google Doc to export |
| folder_id | string | – | Drive folder ID to save PDF in (optional - if not provided, saves in root) |
| pdf_filename | string | – | Name for the PDF file (optional - if not provided, uses original name + "_PDF") |
| user_google_email | string | yes | User's Google email address |
| Name | Type | Req | Description |
|---|---|---|---|
| result | string | yes | – |
No examples provided.
find_and_replace_doc Find and Replace Doc ~196
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.
| Name | Type | Req | Description |
|---|---|---|---|
| document_id | string | yes | ID of the document to update |
| find_text | string | yes | Text to search for |
| match_case | boolean | – | Whether to match case exactly |
| replace_text | string | yes | Text to replace with |
| tab_id | – | – | Optional ID of the tab to target |
| user_google_email | string | yes | User's Google email address |
| Name | Type | Req | Description |
|---|---|---|---|
| result | string | yes | – |
No examples provided.
format_sheet_range Format Sheet Range ~291
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.
| Name | Type | Req | Description |
|---|---|---|---|
| background_color | – | – | Hex background color (e.g., "#FFEECC"). |
| bold | – | – | Whether to apply bold formatting. |
| font_size | – | – | Font size in points. |
| horizontal_alignment | – | – | Horizontal text alignment - LEFT, CENTER, or RIGHT. |
| italic | – | – | Whether to apply italic formatting. |
| number_format_pattern | – | – | Custom pattern for the number format. |
| number_format_type | – | – | Sheets number format type (e.g., "DATE"). |
| range_name | string | yes | A1-style range (optionally with sheet name). Required. |
| spreadsheet_id | string | yes | The ID of the spreadsheet. Required. |
| text_color | – | – | Hex text color (e.g., "#000000"). |
| user_google_email | string | yes | The user's Google email address. Required. |
| vertical_alignment | – | – | Vertical text alignment - TOP, MIDDLE, or BOTTOM. |
| wrap_strategy | – | – | Text wrap strategy - WRAP (wrap text within cell), CLIP (clip text at cell boundary), or OVERFLOW_CELL (allow text to overflow into adjacent empty cells). |
| Name | Type | Req | Description |
|---|---|---|---|
| result | string | yes | – |
No examples provided.
generate_trigger_code Generate Trigger Code ~349
Generates Apps Script code for creating triggers. The Apps Script API cannot create triggers directly - they must be created from within Apps Script itself. This tool generates the code you need.
| Name | Type | Req | Description |
|---|---|---|---|
| function_name | string | yes | The function to run when trigger fires (e.g., "sendDailyReport") |
| schedule | string | – | Schedule details (depends on trigger_type): - For time_minutes: "1", "5", "10", "15", or "30" - For time_hours: "1", "2", "4", "6", "8", or "12" - For time_daily: hour as "0"-"23" (… |
| trigger_type | string | yes | Type of trigger. One of: - "time_minutes" (run every N minutes: 1, 5, 10, 15, 30) - "time_hours" (run every N hours: 1, 2, 4, 6, 8, 12) - "time_daily" (run daily at a sp… |
| Name | Type | Req | Description |
|---|---|---|---|
| result | string | yes | – |
No examples provided.
get_contact Get Contact ~65
Get detailed information about a specific contact.
| Name | Type | Req | Description |
|---|---|---|---|
| contact_id | string | yes | The contact ID (e.g., "c1234567890" or full resource name "people/c1234567890"). |
| user_google_email | string | yes | The user's Google email address. Required. |
| Name | Type | Req | Description |
|---|---|---|---|
| result | string | yes | – |
No examples provided.
get_contact_group Get Contact Group ~73
Get details of a specific contact group including its members.
| Name | Type | Req | Description |
|---|---|---|---|
| group_id | string | yes | The contact group ID. |
| max_members | integer | – | Maximum number of members to return (default: 100, max: 1000). |
| user_google_email | string | yes | The user's Google email address. Required. |
| Name | Type | Req | Description |
|---|---|---|---|
| result | string | yes | – |
No examples provided.
get_doc_as_markdown Get Doc as Markdown ~358
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.
| Name | Type | Req | Description |
|---|---|---|---|
| comment_mode | string | – | How to display comments: - "inline": Footnote-style references placed at the anchor text location (default) - "appendix": All comments grouped at the bottom with blockquoted anchor text - "none": No… |
| document_id | string | yes | ID of the Google Doc (or full URL) |
| include_comments | boolean | – | Whether to include comments (default: True) |
| include_resolved | boolean | – | Whether to include resolved comments (default: False) |
| suggestions_view_mode | string | – | How to render suggestions in the returned content: - "DEFAULT_FOR_CURRENT_ACCESS": Default based on user's access level - "SUGGESTIONS_INLINE": Suggested changes appear inline in the document - "PREV… |
| tab_id | – | – | Optional ID of a single tab to read (from inspect_doc_structure). When given, only that tab's content is rendered, without its child tabs and without a tab heading. When omitted, every tab is rendere… |
| user_google_email | string | yes | User's Google email address |
| Name | Type | Req | Description |
|---|---|---|---|
| result | string | yes | – |
No examples provided.
get_doc_content Get Doc Content ~496
Retrieves content of a Google Doc or a Drive file (like .docx) identified by document_id. - Native Google Docs: Fetches content via Docs API. - Office files (.docx, etc.) stored in Drive: Downloads via Drive API and extracts text. By default, native Google Docs text is index-aligned with the document: empty paragraphs are preserved and every non-text element that occupies an index (inline object, page break, footnote reference, ...) is rendered as one U+FFFC placeholder per index. The document body starts at index 1, so an offset n into the text that follows "--- CONTENT ---" is document index n + 1, and that index can be passed straight to format_text or delete_text. Tables and multi-tab documents interleave separators, so alignment holds up to the first table or tab header. Set preserve_context=True for readable link destinations, internal targets, smart-chip values, table boundaries, headers, footers, footnotes, and object context exposed by the Docs API. This output is plain text, not Markdown, and its offsets must not be used as document editing indices. Comments, revision history, exact visual layout, and chip details hidden by the API are not included. Use get_doc_as_markdown for formatting or comments.
| Name | Type | Req | Description |
|---|---|---|---|
| document_id | string | yes | ID of the Google Doc (or full URL) |
| preserve_context | boolean | – | Include readable semantic annotations for native Docs. Defaults to False to retain index alignment. Office extraction is unaffected. With tab_id, only the selected tab is rendered. |
| suggestions_view_mode | string | – | How to render suggestions in the returned content: - "DEFAULT_FOR_CURRENT_ACCESS": Default based on user's access level - "SUGGESTIONS_INLINE": Suggested changes appear inline in the document - "PREV… |
| tab_id | – | – | Optional ID of a single tab to read (from inspect_doc_structure). When given, only that tab's content is returned with no tab separator, so the default output stays index-aligned with that tab. When… |
| user_google_email | string | yes | User's Google email address |
| Name | Type | Req | Description |
|---|---|---|---|
| result | string | yes | – |
No examples provided.
get_drive_file_content Get Drive File Content ~156
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.
| Name | Type | Req | Description |
|---|---|---|---|
| file_id | string | yes | Drive file ID. |
| user_google_email | string | yes | The user’s Google email address. |
| Name | Type | Req | Description |
|---|---|---|---|
| result | string | yes | – |
No examples provided.
get_drive_file_download_url Get Drive File Download URL ~242
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: - Google Docs -> PDF (default) or DOCX if export_format='docx' - Google Sheets -> XLSX (default), PDF if export_format='pdf', or CSV if export_format='csv' - Google Slides -> PDF (default) or PPTX if export_format='pptx' For other files, downloads the original file format.
| Name | Type | Req | Description |
|---|---|---|---|
| export_format | – | – | Optional export format for Google native files. Options: 'pdf', 'docx', 'xlsx', 'csv', 'pptx'. If not specified, uses sensible defaults (PDF for Docs/Slides, XLSX for Sheets).… |
| file_id | string | yes | The Google Drive file ID to download. |
| user_google_email | string | yes | The user's Google email address. Required. |
| Name | Type | Req | Description |
|---|---|---|---|
| result | string | yes | – |
No examples provided.
get_drive_file_permissions Get Drive File Permissions ~65
Gets detailed metadata about a Google Drive file including sharing permissions, parent folder IDs, ownership, and lifecycle timestamps.
| Name | Type | Req | Description |
|---|---|---|---|
| file_id | string | yes | The ID of the file to check permissions for. |
| user_google_email | string | yes | The user's Google email address. Required. |
| Name | Type | Req | Description |
|---|---|---|---|
| result | string | yes | – |
No examples provided.
get_drive_shareable_link Get Drive Shareable Link ~64
Gets the shareable link for a Google Drive file or folder.
| Name | Type | Req | Description |
|---|---|---|---|
| file_id | string | yes | The ID of the file or folder to get the shareable link for. Required. |
| user_google_email | string | yes | The user's Google email address. Required. |
| Name | Type | Req | Description |
|---|---|---|---|
| result | string | yes | – |
No examples provided.
get_events Get Events ~616
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.
| Name | Type | Req | Description |
|---|---|---|---|
| calendar_id | string | – | The ID of the calendar to query. Use 'primary' for the user's primary calendar. Defaults to 'primary'. Calendar IDs can be obtained using `list_calendars`. |
| detailed | boolean | – | Whether to return detailed event information including description, location, colour (colorId), attendees, and attendee details (response status, organizer, optional flags). Recurring instances also… |
| event_id | – | – | The ID of a specific event to retrieve. If provided, retrieves only this event and ignores time filtering parameters. |
| include_attachments | boolean | – | Whether to include attachment information in detailed event output. When True, shows attachment details (fileId, fileUrl, mimeType, title) for events that have attachments. Only applies when detailed… |
| max_results | integer | – | The maximum number of events to return in one page. Defaults to 25. Ignored if event_id is provided. |
| page_token | – | – | Token for the next page, taken from a previous response. When single_events=True, also pass the response's Pagination time_min as time_min, even if omitted on the first call. Keep all other query par… |
| query | – | – | A keyword to search for within event fields (summary, description, location). Ignored if event_id is provided. |
| single_events | boolean | – | Whether to expand recurring series into individual instances. Defaults to True for backwards compatibility. Set to False with detailed=True to retrieve recurring master events and their exact RFC5545… |
| time_max | – | – | The end of the time range (exclusive) in RFC3339 format. If omitted, events starting from `time_min` onwards are considered (up to `max_results`). Ignored if event_id is provided. |
| time_min | – | – | The start of the time range (inclusive) in RFC3339 format (e.g., '2024-05-12T10:00:00Z' or '2024-05-12'). If omitted, defaults to the current time when single_events=True. It is omitted from unexpand… |
| user_google_email | string | yes | The user's Google email address. Required. |
| Name | Type | Req | Description |
|---|---|---|---|
| result | string | yes | – |
No examples provided.
get_form Get Form ~43
Get a form.
| Name | Type | Req | Description |
|---|---|---|---|
| form_id | string | yes | The ID of the form to retrieve. |
| user_google_email | string | yes | The user's Google email address. Required. |
| Name | Type | Req | Description |
|---|---|---|---|
| result | string | yes | – |
No examples provided.
get_form_response Get Form Response ~60
Get one response from the form.
| Name | Type | Req | Description |
|---|---|---|---|
| form_id | string | yes | The ID of the form. |
| response_id | string | yes | The ID of the response to retrieve. |
| user_google_email | string | yes | The user's Google email address. Required. |
| Name | Type | Req | Description |
|---|---|---|---|
| result | string | yes | – |
No examples provided.
get_gmail_attachment_content Get Gmail Attachment Content ~273
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.
| Name | Type | Req | Description |
|---|---|---|---|
| attachment_id | string | yes | The ID of the attachment to download. |
| attachment_index | – | – | Zero-based attachment position from the message-content response. When the cap is enabled, this lets the server safely resolve Gmail's refreshed attachment IDs against current metadata before downloa… |
| message_id | string | yes | The ID of the Gmail message containing the attachment. |
| return_base64 | boolean | – | When True, includes the full attachment as a standard base64 string in the response (in addition to any file path or download URL). Useful for sandboxed clients that cannot reach localhost download U… |
| user_google_email | string | yes | The user's Google email address. Required. |
| Name | Type | Req | Description |
|---|---|---|---|
| result | string | yes | – |
No examples provided.
get_gmail_message_content Get Gmail Message Content ~301
Retrieves the full content (subject, sender, recipients, body) of a specific Gmail message. Bodies are returned inline and truncated at 20,000 characters. Set full=True to get the complete, untruncated message instead: it is exported to disk and the response carries a short-lived download URL (HTTP transport) or file path (stdio transport) rather than the body, so large messages never stream through the model context. Stateless deployments have no file storage, so there full=True returns the untruncated body inline.
| Name | Type | Req | Description |
|---|---|---|---|
| body_format | string | – | Body output format. 'text' (default) returns plaintext (HTML converted to text as fallback). 'html' returns the raw HTML body as-is without conversion. 'raw' fetches the full raw MIME message and ret… |
| full | boolean | – | When True, return the COMPLETE untruncated message: saved to local storage and referenced by download URL/file path instead of the body text, or inlined in the response when the server has no file st… |
| message_id | string | yes | The unique ID of the Gmail message to retrieve. |
| user_google_email | string | yes | The user's Google email address. Required. |
| Name | Type | Req | Description |
|---|---|---|---|
| result | string | yes | – |
No examples provided.
get_gmail_messages_content_batch Get Gmail Messages Content Batch ~164
Retrieves the content of multiple Gmail messages in a single batch request. Supports up to 25 messages per batch to prevent SSL connection exhaustion.
| Name | Type | Req | Description |
|---|---|---|---|
| body_format | string | – | Body output format (only applies when format='full'). 'text' (default) returns plaintext (HTML converted to text as fallback). 'html' returns the raw HTML body as-is without conversion. 'raw' fetches… |
| format | string | – | Message format. "full" includes body, "metadata" only headers. |
| message_ids | array | yes | List of Gmail message IDs to retrieve (max 25 per batch). |
| user_google_email | string | yes | The user's Google email address. Required. |
| Name | Type | Req | Description |
|---|---|---|---|
| result | string | yes | – |
No examples provided.
get_gmail_thread_content Get Gmail Thread Content ~219
Retrieves the complete content of a Gmail conversation thread, including all messages. Optionally also returns structured ownership analysis so a caller can determine who sent the last message and who owes whom a response without re-parsing the formatted string or making a second tool call.
| Name | Type | Req | Description |
|---|---|---|---|
| body_format | string | – | Body output format. 'text' (default) returns plaintext (HTML converted to text as fallback). 'html' returns the raw HTML body as-is without conversion. 'raw' fetches each message's full raw MIME cont… |
| include_analysis | boolean | – | When True, the return value is a dict with both the formatted thread content AND structured ownership analysis (last sender, ball-in-court verdict, per-sender message counts, participants). Defaults… |
| thread_id | string | yes | The unique ID of the Gmail thread to retrieve. |
| user_google_email | string | yes | The user's Google email address. Required. |
| Name | Type | Req | Description |
|---|---|---|---|
| result | – | yes | – |
No examples provided.
get_gmail_threads_content_batch Get Gmail Threads Content Batch ~145
Retrieves the content of multiple Gmail threads in a single batch request. Supports up to 25 threads per batch to prevent SSL connection exhaustion.
| Name | Type | Req | Description |
|---|---|---|---|
| body_format | string | – | Body output format. 'text' (default) returns plaintext (HTML converted to text as fallback). 'html' returns the raw HTML body as-is without conversion. 'raw' fetches each message's full raw MIME cont… |
| thread_ids | array | yes | A list of Gmail thread IDs to retrieve. The function will automatically batch requests in chunks of 25. |
| user_google_email | string | yes | The user's Google email address. Required. |
| Name | Type | Req | Description |
|---|---|---|---|
| result | string | yes | – |
No examples provided.
get_messages Get Messages ~156
Retrieves messages from a Google Chat space.
| Name | Type | Req | Description |
|---|---|---|---|
| message_filter | – | – | Optional filter string using the Chat API filter syntax. Supports createTime and thread.name. Examples: 'createTime > "2026-03-18T00:00:00-03:00"'… |
| order_by | string | – | – |
| page_size | integer | – | – |
| space_id | string | yes | – |
| user_google_email | string | yes | – |
| Name | Type | Req | Description |
|---|---|---|---|
| result | string | yes | – |
No examples provided.
get_page Get Page ~168
Get details about a specific page (slide) in a presentation.
| Name | Type | Req | Description |
|---|---|---|---|
| include_geometry | boolean | – | Also report each element's placement - its transform (translate, and scale/shear when not identity) and intrinsic size, in raw EMU. Set this when adding elements to an existing deck: it is the only w… |
| page_object_id | string | yes | The object ID of the page/slide to retrieve. |
| presentation_id | string | yes | The ID of the presentation. |
| user_google_email | string | yes | The user's Google email address. Required. |
| Name | Type | Req | Description |
|---|---|---|---|
| result | string | yes | – |
No examples provided.
get_page_thumbnail Get Page Thumbnail ~98
Generate a thumbnail URL for a specific page (slide) in a presentation.
| Name | Type | Req | Description |
|---|---|---|---|
| page_object_id | string | yes | The object ID of the page/slide. |
| presentation_id | string | yes | The ID of the presentation. |
| thumbnail_size | string | – | Size of thumbnail ("LARGE", "MEDIUM", "SMALL"). Defaults to "MEDIUM". |
| user_google_email | string | yes | The user's Google email address. Required. |
| Name | Type | Req | Description |
|---|---|---|---|
| result | string | yes | – |
No examples provided.
get_presentation Get Presentation ~197
Get details about a Google Slides presentation.
| Name | Type | Req | Description |
|---|---|---|---|
| include_geometry | boolean | – | Also list each slide's elements with their placement - transform (translate, and scale/shear when not identity) and intrinsic size, in raw EMU. Set this when adding slides to an existing deck so new… |
| include_speaker_notes | boolean | – | Also report each slide's speaker (presenter) notes and the object ID of the shape holding them. Pass True when you need to read or edit notes: that shape ID is the only valid target for insertText/de… |
| presentation_id | string | yes | The ID of the presentation to retrieve. |
| user_google_email | string | yes | The user's Google email address. Required. |
| Name | Type | Req | Description |
|---|---|---|---|
| result | string | yes | – |
No examples provided.
get_script_content Get Script Content ~58
Retrieves content of a specific file within a project.
| Name | Type | Req | Description |
|---|---|---|---|
| file_name | string | yes | Name of the file to retrieve |
| script_id | string | yes | The script project ID |
| user_google_email | string | yes | User's email address |
| Name | Type | Req | Description |
|---|---|---|---|
| result | string | yes | – |
No examples provided.
get_script_metrics Get Script Metrics ~82
Gets execution metrics for a script project. Returns analytics data including active users, total executions, and failed executions over time.
| Name | Type | Req | Description |
|---|---|---|---|
| metrics_granularity | string | – | Granularity of metrics - "DAILY" or "WEEKLY" |
| script_id | string | yes | The script project ID |
| user_google_email | string | yes | User's email address |
| Name | Type | Req | Description |
|---|---|---|---|
| result | string | yes | – |
No examples provided.
What is the io.github.taylorwilsdon/workspace-mcp server?
io.github.taylorwilsdon/workspace-mcp is listed in the public MCP registry as io.github.taylorwilsdon/workspace-mcp. Google Workspace MCP server for Gmail, Drive, Calendar, Docs, Sheets, Slides, Forms, Tasks, Chat. This page covers its PyPI package (workspace-mcp).
Is the io.github.taylorwilsdon/workspace-mcp server safe to use?
io.github.taylorwilsdon/workspace-mcp scores 58 out of 100 on VerifyMCP. We found no known CVEs affecting it as of 20 September 2026. That is a record of what we were able to check automatically, not an endorsement. The category breakdown on this page shows every signal behind the number, including the ones we could not confirm.
What tools does the io.github.taylorwilsdon/workspace-mcp server expose?
io.github.taylorwilsdon/workspace-mcp exposes 123 tools: start_google_auth, search_gmail_messages, get_gmail_message_content, get_gmail_messages_content_batch, get_gmail_attachment_content, and 118 more. Their descriptions and schemas cost roughly 26,154 tokens of context every time the server is loaded.
Is the io.github.taylorwilsdon/workspace-mcp server still maintained?
io.github.taylorwilsdon/workspace-mcp is still listed as active in the MCP registry. We last reached this channel on 20 September 2026. Those dates come from our own scans of the registry and the channel itself, not from anything the publisher announced.