@bohachu/google-slides-mcp
Version:
MCP server for Google Slides integration with service account authentication
489 lines (398 loc) • 21.4 kB
Markdown
# 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