Skip to main content
Glama

Google Workspace MCP Server - Control Gmail, Calendar, Docs, Sheets, Slides, Chat, Forms & Drive

slides_tools.py10.2 kB
""" Google Slides MCP Tools This module provides MCP tools for interacting with Google Slides API. """ import logging import asyncio from typing import List, Dict, Any from auth.service_decorator import require_google_service from core.server import server from core.utils import handle_http_errors from core.comments import create_comment_tools logger = logging.getLogger(__name__) @server.tool() @handle_http_errors("create_presentation", service_type="slides") @require_google_service("slides", "slides") async def create_presentation( service, user_google_email: str, title: str = "Untitled Presentation" ) -> str: """ Create a new Google Slides presentation. Args: user_google_email (str): The user's Google email address. Required. title (str): The title for the new presentation. Defaults to "Untitled Presentation". Returns: str: Details about the created presentation including ID and URL. """ logger.info(f"[create_presentation] Invoked. Email: '{user_google_email}', Title: '{title}'") body = { 'title': title } result = await asyncio.to_thread( service.presentations().create(body=body).execute ) presentation_id = result.get('presentationId') presentation_url = f"https://docs.google.com/presentation/d/{presentation_id}/edit" confirmation_message = f"""Presentation Created Successfully for {user_google_email}: - Title: {title} - Presentation ID: {presentation_id} - URL: {presentation_url} - Slides: {len(result.get('slides', []))} slide(s) created""" logger.info(f"Presentation created successfully for {user_google_email}") return confirmation_message @server.tool() @handle_http_errors("get_presentation", is_read_only=True, service_type="slides") @require_google_service("slides", "slides_read") async def get_presentation( service, user_google_email: str, presentation_id: str ) -> str: """ Get details about a Google Slides presentation. Args: user_google_email (str): The user's Google email address. Required. presentation_id (str): The ID of the presentation to retrieve. Returns: str: Details about the presentation including title, slides count, and metadata. """ logger.info(f"[get_presentation] Invoked. Email: '{user_google_email}', ID: '{presentation_id}'") result = await asyncio.to_thread( service.presentations().get(presentationId=presentation_id).execute ) title = result.get('title', 'Untitled') slides = result.get('slides', []) page_size = result.get('pageSize', {}) slides_info = [] for i, slide in enumerate(slides, 1): slide_id = slide.get('objectId', 'Unknown') page_elements = slide.get('pageElements', []) slides_info.append(f" Slide {i}: ID {slide_id}, {len(page_elements)} element(s)") confirmation_message = f"""Presentation Details for {user_google_email}: - Title: {title} - Presentation ID: {presentation_id} - URL: https://docs.google.com/presentation/d/{presentation_id}/edit - Total Slides: {len(slides)} - Page Size: {page_size.get('width', {}).get('magnitude', 'Unknown')} x {page_size.get('height', {}).get('magnitude', 'Unknown')} {page_size.get('width', {}).get('unit', '')} Slides Breakdown: {chr(10).join(slides_info) if slides_info else ' No slides found'}""" logger.info(f"Presentation retrieved successfully for {user_google_email}") return confirmation_message @server.tool() @handle_http_errors("batch_update_presentation", service_type="slides") @require_google_service("slides", "slides") async def batch_update_presentation( service, user_google_email: str, presentation_id: str, requests: List[Dict[str, Any]] ) -> str: """ Apply batch updates to a Google Slides presentation. Args: user_google_email (str): The user's Google email address. Required. presentation_id (str): The ID of the presentation to update. requests (List[Dict[str, Any]]): List of update requests to apply. Returns: str: Details about the batch update operation results. """ logger.info(f"[batch_update_presentation] Invoked. Email: '{user_google_email}', ID: '{presentation_id}', Requests: {len(requests)}") body = { 'requests': requests } result = await asyncio.to_thread( service.presentations().batchUpdate( presentationId=presentation_id, body=body ).execute ) replies = result.get('replies', []) confirmation_message = f"""Batch Update Completed for {user_google_email}: - Presentation ID: {presentation_id} - URL: https://docs.google.com/presentation/d/{presentation_id}/edit - Requests Applied: {len(requests)} - Replies Received: {len(replies)}""" if replies: confirmation_message += "\n\nUpdate Results:" for i, reply in enumerate(replies, 1): if 'createSlide' in reply: slide_id = reply['createSlide'].get('objectId', 'Unknown') confirmation_message += f"\n Request {i}: Created slide with ID {slide_id}" elif 'createShape' in reply: shape_id = reply['createShape'].get('objectId', 'Unknown') confirmation_message += f"\n Request {i}: Created shape with ID {shape_id}" else: confirmation_message += f"\n Request {i}: Operation completed" logger.info(f"Batch update completed successfully for {user_google_email}") return confirmation_message @server.tool() @handle_http_errors("get_page", is_read_only=True, service_type="slides") @require_google_service("slides", "slides_read") async def get_page( service, user_google_email: str, presentation_id: str, page_object_id: str ) -> str: """ Get details about a specific page (slide) in a presentation. Args: user_google_email (str): The user's Google email address. Required. presentation_id (str): The ID of the presentation. page_object_id (str): The object ID of the page/slide to retrieve. Returns: str: Details about the specific page including elements and layout. """ logger.info(f"[get_page] Invoked. Email: '{user_google_email}', Presentation: '{presentation_id}', Page: '{page_object_id}'") result = await asyncio.to_thread( service.presentations().pages().get( presentationId=presentation_id, pageObjectId=page_object_id ).execute ) page_type = result.get('pageType', 'Unknown') page_elements = result.get('pageElements', []) elements_info = [] for element in page_elements: element_id = element.get('objectId', 'Unknown') if 'shape' in element: shape_type = element['shape'].get('shapeType', 'Unknown') elements_info.append(f" Shape: ID {element_id}, Type: {shape_type}") elif 'table' in element: table = element['table'] rows = table.get('rows', 0) cols = table.get('columns', 0) elements_info.append(f" Table: ID {element_id}, Size: {rows}x{cols}") elif 'line' in element: line_type = element['line'].get('lineType', 'Unknown') elements_info.append(f" Line: ID {element_id}, Type: {line_type}") else: elements_info.append(f" Element: ID {element_id}, Type: Unknown") confirmation_message = f"""Page Details for {user_google_email}: - Presentation ID: {presentation_id} - Page ID: {page_object_id} - Page Type: {page_type} - Total Elements: {len(page_elements)} Page Elements: {chr(10).join(elements_info) if elements_info else ' No elements found'}""" logger.info(f"Page retrieved successfully for {user_google_email}") return confirmation_message @server.tool() @handle_http_errors("get_page_thumbnail", is_read_only=True, service_type="slides") @require_google_service("slides", "slides_read") async def get_page_thumbnail( service, user_google_email: str, presentation_id: str, page_object_id: str, thumbnail_size: str = "MEDIUM" ) -> str: """ Generate a thumbnail URL for a specific page (slide) in a presentation. Args: user_google_email (str): The user's Google email address. Required. presentation_id (str): The ID of the presentation. page_object_id (str): The object ID of the page/slide. thumbnail_size (str): Size of thumbnail ("LARGE", "MEDIUM", "SMALL"). Defaults to "MEDIUM". Returns: str: URL to the generated thumbnail image. """ logger.info(f"[get_page_thumbnail] Invoked. Email: '{user_google_email}', Presentation: '{presentation_id}', Page: '{page_object_id}', Size: '{thumbnail_size}'") result = await asyncio.to_thread( service.presentations().pages().getThumbnail( presentationId=presentation_id, pageObjectId=page_object_id, thumbnailProperties_thumbnailSize=thumbnail_size, thumbnailProperties_mimeType='PNG' ).execute ) thumbnail_url = result.get('contentUrl', '') confirmation_message = f"""Thumbnail Generated for {user_google_email}: - Presentation ID: {presentation_id} - Page ID: {page_object_id} - Thumbnail Size: {thumbnail_size} - Thumbnail URL: {thumbnail_url} You can view or download the thumbnail using the provided URL.""" logger.info(f"Thumbnail generated successfully for {user_google_email}") return confirmation_message # Create comment management tools for slides _comment_tools = create_comment_tools("presentation", "presentation_id") read_presentation_comments = _comment_tools['read_comments'] create_presentation_comment = _comment_tools['create_comment'] reply_to_presentation_comment = _comment_tools['reply_to_comment'] resolve_presentation_comment = _comment_tools['resolve_comment'] # Aliases for backwards compatibility and intuitive naming read_slide_comments = read_presentation_comments create_slide_comment = create_presentation_comment reply_to_slide_comment = reply_to_presentation_comment resolve_slide_comment = resolve_presentation_comment

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/taylorwilsdon/google_workspace_mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server