UNPKG

@bohachu/google-slides-mcp

Version:

MCP server for Google Slides integration with service account authentication

489 lines (398 loc) 21.4 kB
# Google Slides MCP Server ## Description This project provides a Model Context Protocol (MCP) server for interacting with the Google Slides API. It allows you to create, read, modify, and manage Google Slides presentations programmatically through a secure service account authentication method. ## Quick Start for Gemini CLI (Primary Method) ### Complete Setup Instructions Follow these step-by-step instructions to set up the Google Slides MCP server with Gemini CLI: 1. **Create working directory** ```bash mkdir ~/coding_projects/working ``` 2. **Navigate to working directory** ```bash cd ~/coding_projects/working ``` 3. **Create keys directory for Google service account** ```bash mkdir -p ~/coding_projects/working/keys ``` 4. **Copy your Google service account key** - Drag and drop your `google_service_account_key.json` file to the directory: `~/coding_projects/working/keys` - Make sure the file is named exactly `google_service_account_key.json` 5. **Create .env file with Gemini API key** ```bash vi ~/coding_projects/working/.env ``` - Press `i` to enter insert mode - Type: `GEMINI_API_KEY=your_actual_api_key_here` - Press `ESC`, then type `:wq` and press `Enter` to save and exit 6. **Create MCP configuration directory** ```bash mkdir -p ~/coding_projects/working/.gemini ``` 7. **Configure MCP settings** ```bash vi ~/coding_projects/working/.gemini/settings.json ``` - Press `i` to enter insert mode - Insert the following content: ```json { "mcpServers": { "google-slides-mcp": { "command": "google-slides-mcp" } } } ``` - Press `ESC`, then type `:wq` and press `Enter` to save and exit 8. **Install the Google Slides MCP server globally** Remember to execute this command in your terminal first: ```bash npm install -g @bohachu/google-slides-mcp ``` This installs the remote MCP server to your local machine globally, making it executable from any path. 9. **Verify installation** ```bash gemini -y ``` You should now see that the Google Slides MCP server environment is installed and ready to use. ### Quick Setup (After Initial Installation) Once you've completed the initial setup, for subsequent use you only need: ```bash export GOOGLE_API_KEY="YOUR_API_KEY" ``` Install the MCP server globally: ```bash npm install -g @bohachu/google-slides-mcp ``` Then edit `~/.gemini/settings.json` to add the Google Slides MCP server: ```json { "mcpServers": { "google-slides-mcp": { "command": "google-slides-mcp" } } } ``` Note: The service account key file must be present at `keys/google_service_account_key.json` relative to your working directory when using Gemini CLI. ### 2. Set up Google Service Account Authentication 1. Go to the [Google Cloud Console](https://console.cloud.google.com/) 2. Create a new project or select an existing one 3. Enable the Google Slides API: - Navigate to "APIs & Services" > "Enabled APIs & services" - Click "+ ENABLE APIS AND SERVICES" - Search for "Google Slides API" and enable it 4. Create Service Account credentials: - Navigate to "APIs & Services" > "Credentials" - Click "+ CREATE CREDENTIALS" > "Service account" - Fill in the service account details - Click "Create" and "Done" 5. Download the service account key: - Click on your newly created service account - Go to the "Keys" tab - Click "Add Key" > "Create new key" - Choose "JSON" as the key type - Click "Create" to download the JSON file 6. **Important:** Rename the downloaded file to `google_service_account_key.json` and place it in a `keys` directory in your current working directory ### 3. Use with Gemini CLI Once configured, you can use the Google Slides tools directly in Gemini CLI. The MCP server will be automatically loaded when you start Gemini. ## Other Installation Methods ### Build from Source If you want to build from source or contribute to the project: ```bash # Clone the repository git clone https://github.com/bohachu/botrun-google-slides-mcp.git cd botrun-google-slides-mcp # Install dependencies npm install # Build the project npm run build ``` ## Prerequisites * Node.js (v18 or later recommended) * npm (usually comes with Node.js) * Google Cloud Project with the Google Slides API enabled. * Service Account credentials for your Google Cloud Project. ## Setup 1. **Clone the repository (if applicable) or ensure you are in the project directory.** 2. **Install dependencies:** ```bash npm install ``` 3. **Build the Server:** Compile the TypeScript code to JavaScript: ```bash npm run build ``` This will create a `build` directory containing the compiled JavaScript code. 4. **Set up Authentication:** This project uses Google Service Account authentication for better security and easier deployment. **Obtain Google Service Account Credentials:** * Go to the [Google Cloud Console](https://console.cloud.google.com/). * Create a new project or select an existing one. * Navigate to "APIs & Services" > "Enabled APIs & services". * Click "+ ENABLE APIS AND SERVICES", search for "Google Slides API", and enable it. * Navigate to "APIs & Services" > "Credentials". * Click "+ CREATE CREDENTIALS" > "Service account". * Fill in the service account details: * Service account name (e.g., "slides-mcp-service") * Service account ID (will be auto-generated) * Service account description (optional) * Click "Create". * Skip the optional steps for granting roles and user access. * Click "Done". * Find your newly created service account in the list and click on it. * Go to the "Keys" tab. * Click "Add Key" > "Create new key". * Choose "JSON" as the key type. * Click "Create". A JSON file will be downloaded to your computer. * **Important:** Rename this file to `google_service_account_key.json` and place it in the `keys` directory of this project. 5. **Grant Permissions (if needed):** * If you need to access specific Google Slides presentations that are not owned by the service account: * Share the presentations with the service account email (found in the JSON key file as `client_email`) * Grant at least "Editor" permissions for full functionality ## Acknowledgments This project is based on the original work by Matteo Antoci: [google-slides-mcp](https://github.com/matteoantoci/google-slides-mcp). The original project is licensed under GPL-3.0, and this modified version maintains the same license. We are grateful to Matteo Antoci and all contributors to the original project for creating this foundation. ### Major Changes from Original: - **Authentication Method**: Changed from OAuth 2.0 with refresh tokens to Service Account authentication for improved security and easier deployment - **New Features**: - Added `move_presentation` tool for moving/copying presentations to Google Drive folders - Added `get_slides` tool for paginated slide reading to handle large presentations - Added `get_slide_preview` tool for visual preview/thumbnail generation - Added `duplicate_presentation` tool for creating complete presentation copies - Added `get_slide_text_elements` tool for extracting all text elements with IDs and styles - Added `replace_text_by_element` tool for precise text replacement while preserving formatting - Added `analyze_template_structure` tool for understanding presentation patterns and content mapping - **Enhanced Security**: Using service account key file stored locally instead of environment variables for credentials - **Drive API Integration**: Added Google Drive API scopes to support file management operations - **Performance Improvements**: Pagination support to handle large presentations without token limits - **Text Manipulation**: Complete text element access and replacement capabilities for template customization ## MCP Configuration for Other Tools This MCP server can also be used with other AI tools that support the Model Context Protocol: ### Claude Desktop **Configuration file location:** - **macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json` - **Windows**: `%APPDATA%\Claude\claude_desktop_config.json` **Configuration (after global installation):** ```json { "mcpServers": { "google-slides-mcp": { "command": "google-slides-mcp" } } } ``` **Note:** First install globally with `npm install -g @bohachu/google-slides-mcp` After editing the configuration: 1. Completely quit Claude Desktop 2. Restart Claude Desktop 3. Look for the MCP indicator (🔌) in the bottom-right corner of the chat input ### Claude Code **Using CLI (after global installation):** ```bash # First install globally npm install -g @bohachu/google-slides-mcp # Add the server claude mcp add google-slides google-slides-mcp # For project-specific configuration claude mcp add google-slides -s project google-slides-mcp ``` **Direct configuration file:** - **User config**: `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) - **Project config**: `{project}/.mcp.json` Configuration format: ```json { "mcpServers": { "google-slides-mcp": { "command": "google-slides-mcp" } } } ``` ### Cursor IDE **Configuration file location:** - **Project-specific**: `{project}/.cursor/mcp.json` **Setup steps:** 1. First install globally: `npm install -g @bohachu/google-slides-mcp` 2. Open Settings (`Ctrl+Shift+J` or `Cmd+Shift+J`) 3. Navigate to Features → Model Context Protocol 4. Click "Add" to add a new server 5. Create or edit `.cursor/mcp.json`: ```json { "mcpServers": { "google-slides-mcp": { "command": "google-slides-mcp" } } } ``` 6. Refresh and ensure the server indicator turns green ### Important Notes for All Tools: - First install the server globally: `npm install -g @bohachu/google-slides-mcp` - The service account key must be present at `keys/google_service_account_key.json` relative to the current working directory - No environment variables are needed as the server loads credentials from the key file - After configuration changes, restart the respective tool for changes to take effect - For Windows users, use forward slashes in paths or escape backslashes (e.g., `C:/path/to/file` or `C:\\path\\to\\file`) ### Troubleshooting MCP Connection: - **Claude Desktop/Code**: Check logs at `~/Library/Logs/Claude/mcp*.log` (macOS) or `%APPDATA%\Claude\logs\mcp*.log` (Windows) - **Cursor**: Open Output panel (`Ctrl+Shift+U`) and select "MCP Logs" from dropdown - **Gemini CLI**: Run with `--debug` flag for detailed logging - Ensure Node.js is installed and accessible from command line (`node --version`) - Verify the build directory exists and contains `index.js` after running `npm run build` ## Running the Server Execute the compiled code: ```bash npm run start ``` The server will start and listen for MCP requests on standard input/output (stdio). You should see a message like: `Google Slides MCP server running and connected via stdio.` ## Available Tools The server exposes the following tools via the Model Context Protocol: * **`create_presentation`**: Creates a new Google Slides presentation. * **Input:** * `title` (string, required): The title for the new presentation. * **Output:** JSON object representing the created presentation details. * **`get_presentation`**: Retrieves details about an existing presentation. * **Input:** * `presentationId` (string, required): The ID of the presentation to retrieve. * `fields` (string, optional): A field mask (e.g., "slides,pageSize") to limit the returned data. * **Output:** JSON object representing the presentation details. * **`batch_update_presentation`**: Applies a series of updates to a presentation. This is the primary method for modifying slides (adding text, shapes, images, creating slides, etc.). * **Input:** * `presentationId` (string, required): The ID of the presentation to update. * `requests` (array, required): An array of request objects defining the updates. Refer to the [Google Slides API `batchUpdate` documentation](https://developers.google.com/slides/api/reference/rest/v1/presentations/batchUpdate#requestbody) for the structure of individual requests. * `writeControl` (object, optional): Controls write request execution (e.g., using revision IDs). * **Output:** JSON object representing the result of the batch update. * **`get_page`**: Retrieves details about a specific page (slide) within a presentation. * **Input:** * `presentationId` (string, required): The ID of the presentation containing the page. * `pageObjectId` (string, required): The object ID of the page (slide) to retrieve. * **Output:** JSON object representing the page details. * **`summarize_presentation`**: Extracts and formats all text content from a presentation for easier summarization. * **Input:** * `presentationId` (string, required): The ID of the presentation to summarize. * `include_notes` (boolean, optional): Whether to include speaker notes in the summary. Defaults to false. * **Output:** JSON object containing: * `title`: The presentation's title * `slideCount`: Total number of slides * `lastModified`: Revision information * `slides`: Array of slide objects containing: * `slideNumber`: Position in presentation * `slideId`: Object ID of the slide * `content`: All text extracted from the slide * `notes`: Speaker notes (if requested and available) * **`move_presentation`**: Move or copy a presentation to a specific Google Drive folder. * **Input:** * `presentationId` (string, required): The ID of the presentation to move. * `folderId` (string, required): The ID of the target Google Drive folder. * `copyInstead` (boolean, optional): If true, creates a copy in the target folder instead of moving. Defaults to false. * `newName` (string, optional): New name for the presentation (only used when copyInstead is true). * **Output:** JSON object containing: * `success`: Boolean indicating if the operation was successful * `message`: Description of what happened * `presentationUrl`: URL to access the presentation * **Notes:** * The service account must have appropriate permissions to move files. * If direct moving fails, the tool will try to add the presentation to the folder without removing it from the original location. * As a last resort, it will share the presentation with the folder owner for manual moving. * To extract folder ID from a Google Drive URL: `https://drive.google.com/drive/folders/[FOLDER_ID]` * **`get_slides`**: Get a range of slides from a presentation with pagination support. * **Input:** * `presentationId` (string, required): The ID of the presentation. * `startIndex` (number, optional): The starting slide index (0-based, inclusive). Default: 0 * `endIndex` (number, optional): The ending slide index (0-based, exclusive). Default: all slides * **Output:** JSON object containing: * `presentationId`: The ID of the presentation * `title`: The presentation title * `totalSlides`: Total number of slides in the presentation * `requestedRange`: Object showing the actual range returned * `slides`: Array of slide objects for the requested range * **`get_slide_preview`**: Get a visual preview (thumbnail) of a specific slide. * **Input:** * `presentationId` (string, required): The ID of the presentation. * `slideId` (string, required): The object ID of the slide to preview. * `mimeType` (string, optional): The MIME type of the thumbnail image. Options: 'PNG' or 'JPEG'. Default: 'PNG' * **Output:** JSON object containing: * `presentationId`: The ID of the presentation * `slideId`: The ID of the slide * `mimeType`: The MIME type of the thumbnail * `contentUrl`: Temporary URL to the thumbnail image * `width`: Width of the thumbnail in pixels * `height`: Height of the thumbnail in pixels * `note`: Warning that the contentUrl expires quickly * **`duplicate_presentation`**: Create a complete copy of an existing presentation. * **Input:** * `presentationId` (string, required): The ID of the presentation to duplicate. * `newTitle` (string, required): The title for the new presentation copy. * **Output:** JSON object containing: * `success`: Boolean indicating if the operation was successful * `originalPresentationId`: The ID of the source presentation * `newPresentationId`: The ID of the newly created copy * `newTitle`: The title of the new presentation * `slideCount`: Number of slides in the new presentation * `message`: Description of what happened * **`get_slide_text_elements`**: Extract all text elements from a slide with complete context. * **Input:** * `presentationId` (string, required): The ID of the presentation. * `slideId` (string, required): The object ID of the slide. * `includeStyles` (boolean, optional): Include text formatting information. Default: true * `includePosition` (boolean, optional): Include element position/layout info. Default: true * **Output:** JSON object containing: * `presentationId`: The ID of the presentation * `slideId`: The ID of the slide * `elementCount`: Number of text elements found * `elements`: Array of text element objects containing: * `elementId`: Unique ID of the element * `shapeType`: Type of shape containing the text * `text`: The actual text content * `placeholder`: Placeholder info if applicable * `position`: X, Y, width, height in pixels (if requested) * `textStyle`: Font, size, color, bold, italic, etc. (if requested) * `paragraphStyle`: Alignment, spacing, indentation (if requested) * **`replace_text_by_element`**: Replace text in specific elements while preserving formatting. * **Input:** * `presentationId` (string, required): The ID of the presentation. * `replacements` (array, required): Array of replacement operations: * `elementId` (string, required): The object ID of the element containing text * `newText` (string, required): The new text to insert * `preserveStyle` (boolean, optional): Preserve original text style. Default: true * **Output:** JSON object containing: * `presentationId`: The ID of the presentation * `totalReplacements`: Number of replacements requested * `successfulReplacements`: Number of successful replacements * `replacementDetails`: Array with details of each replacement operation * **`analyze_template_structure`**: Analyze presentation structure to understand text elements and content patterns. * **Input:** * `presentationId` (string, required): The ID of the presentation to analyze. * `slideIndices` (array, optional): Specific slide indices to analyze. If not provided, analyzes all slides. * **Output:** JSON object containing: * `presentationId`: The ID of the presentation * `totalSlides`: Total number of slides * `analyzedSlides`: Number of slides analyzed * `slides`: Array of slide analysis objects with: * `slideIndex`: Position in presentation * `slideId`: Object ID of the slide * `layout`: Layout type (TITLE_SLIDE, TITLE_AND_BODY, etc.) * `textElements`: Array of elements with role, placeholder status, and content suggestions * `insights`: Analysis summary including: * `totalTextElements`: Total count across all slides * `placeholderElements`: Count of placeholder elements * `layoutDistribution`: Distribution of layout types * `elementRoleDistribution`: Distribution of text roles * `recommendedApproach`: Suggestion for content replacement strategy *(More tools can be added by extending `src/index.ts`)* ## License This project is licensed under the GNU General Public License v3.0 - see the [LICENSE](LICENSE) file for details. Original work Copyright (C) 2025 Matteo Antoci Modifications Copyright (C) 2025 Bowen Chiu ## Contributing Contributions are welcome! Please feel free to submit a Pull Request. ## Security Notes - Never commit your `google_service_account_key.json` file to version control - The `keys/` directory should be added to `.gitignore` - Service account keys should be kept secure and rotated regularly - Only grant necessary permissions to the service account