Skip to main content
Glama

update_sheet_titles_tool

Rename multiple sheets in a Google Spreadsheet by specifying existing sheet names and their new titles to organize spreadsheet content.

Instructions

Update sheet titles in a Google Spreadsheet.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
spreadsheet_nameYesThe name of the Google Spreadsheet
sheet_namesYesList of sheet names to rename (put only the names of the sheets you want to rename)
new_titlesYesList of new titles for the sheets

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
resultYes

Implementation Reference

  • Main handler function that executes the tool logic: validates inputs, retrieves spreadsheet and sheet IDs using helpers, checks for duplicate names, performs batch sheet property updates via Google Sheets API, handles errors, and returns a compact JSON response.
    def update_sheet_titles_handler(
        drive_service,
        sheets_service,
        spreadsheet_name: str,
        sheet_names: List[str],
        new_titles: List[str]
    ) -> str:
        """
        Handler to update sheet titles in a Google Spreadsheet.
        
        Args:
            drive_service: Google Drive service
            sheets_service: Google Sheets service
            spreadsheet_name: Name of the spreadsheet
            sheet_names: List of sheet names to update
            new_titles: List of new titles for the sheets
        
        Returns:
            JSON string with success status and updated sheets info
        """
        try:
            # Validate inputs
            if not sheet_names or not isinstance(sheet_names, list):
                return compact_json_response({
                    "success": False,
                    "message": "Sheet names are required and must be a list."
                })
            
            if not new_titles or not isinstance(new_titles, list):
                return compact_json_response({
                    "success": False,
                    "message": "New titles are required and must be a list."
                })
            
            if len(sheet_names) != len(new_titles):
                return compact_json_response({
                    "success": False,
                    "message": "Number of sheet names must match number of new titles."
                })
            
            if len(sheet_names) == 0:
                return compact_json_response({
                    "success": False,
                    "message": "At least one sheet name is required."
                })
            
            # Validate each new title
            valid_titles = []
            invalid_titles = []
            
            for title in new_titles:
                validation = validate_sheet_name(title)
                if validation["valid"]:
                    valid_titles.append(validation["cleaned_name"])
                else:
                    invalid_titles.append({"title": title, "error": validation["error"]})
            
            if invalid_titles:
                error_messages = [f"'{item['title']}': {item['error']}" for item in invalid_titles]
                return compact_json_response({
                    "success": False,
                    "message": f"Invalid sheet titles: {'; '.join(error_messages)}",
                    "invalid_titles": invalid_titles
                })
            
            if not valid_titles:
                return compact_json_response({
                    "success": False,
                    "message": "No valid sheet titles provided."
                })
            
            # Get spreadsheet ID
            spreadsheet_id = get_spreadsheet_id_by_name(drive_service, spreadsheet_name)
            if not spreadsheet_id:
                return compact_json_response({
                    "success": False,
                    "message": f"Spreadsheet '{spreadsheet_name}' not found."
                })
            
            # Get sheet IDs
            sheet_ids = get_sheet_ids_by_names(sheets_service, spreadsheet_id, sheet_names)
            missing_sheets = [name for name in sheet_names if name not in sheet_ids]
            
            if missing_sheets:
                return compact_json_response({
                    "success": False,
                    "message": f"Sheets not found: {', '.join(missing_sheets)}"
                })
            
            # Check for duplicate names
            duplicate_check = check_duplicate_sheet_names_for_update(sheets_service, spreadsheet_id, valid_titles, sheet_names)
            if duplicate_check["has_duplicates"]:
                return compact_json_response({
                    "success": False,
                    "message": duplicate_check["error"]
                })
            
            # Update sheet titles
            try:
                sheet_id_list = [sheet_ids[name] for name in sheet_names]
                updated_names = update_sheet_titles(sheets_service, spreadsheet_id, sheet_id_list, valid_titles)
                
                # Prepare response
                renamed_sheets = list(zip(sheet_names, updated_names))
                response_data = {
                    "success": True,
                    "spreadsheet_name": spreadsheet_name,
                    "renamed_sheets": renamed_sheets,
                    "sheets_renamed": len(updated_names),
                    "message": f"Successfully updated {len(updated_names)} sheet title(s) in '{spreadsheet_name}'"
                }
                
                return compact_json_response(response_data)
                
            except HttpError as e:
                error_details = e.error_details if hasattr(e, 'error_details') else str(e)
                return compact_json_response({
                    "success": False,
                    "message": f"Failed to update sheet titles: {error_details}",
                    "error_code": e.resp.status if hasattr(e, 'resp') else None
                })
            
        except Exception as e:
            return compact_json_response({
                "success": False,
                "message": f"Unexpected error: {str(e)}",
                "error_type": type(e).__name__
            })
  • Registers the MCP tool 'update_sheet_titles_tool' with @mcp.tool() decorator, defines input schema using Pydantic Field for spreadsheet_name, sheet_names, and new_titles parameters, initializes Google services, and delegates execution to the handler function.
    @mcp.tool()
    def update_sheet_titles_tool(
        spreadsheet_name: str = Field(..., description="The name of the Google Spreadsheet"),
        sheet_names: List[str] = Field(..., description="List of sheet names to rename (put only the names of the sheets you want to rename)"),
        new_titles: List[str] = Field(..., description="List of new titles for the sheets")
    ) -> str:
        """
        Update sheet titles in a Google Spreadsheet.
        """
        sheets_service, drive_service = _get_google_services()
        return update_sheet_titles_handler(drive_service, sheets_service, spreadsheet_name, sheet_names, new_titles)
  • Input schema definition for the tool using Pydantic BaseModel Field with descriptions and required parameters.
        spreadsheet_name: str = Field(..., description="The name of the Google Spreadsheet"),
        sheet_names: List[str] = Field(..., description="List of sheet names to rename (put only the names of the sheets you want to rename)"),
        new_titles: List[str] = Field(..., description="List of new titles for the sheets")
    ) -> str:
  • Core helper function that constructs the batchUpdate requests to rename multiple sheets using Google Sheets API and extracts the updated titles from the response.
    def update_sheet_titles(sheets_service, spreadsheet_id: str, sheet_ids: List[int], new_titles: List[str]) -> List[str]:
        """
        Update sheet titles in a Google Spreadsheet.
        
        Args:
            sheets_service: Google Sheets service
            spreadsheet_id: ID of the spreadsheet
            sheet_ids: List of sheet IDs to update
            new_titles: List of new titles for the sheets
        
        Returns:
            List of updated sheet names
        """
        requests = []
        for sheet_id, new_title in zip(sheet_ids, new_titles):
            requests.append({
                "updateSheetProperties": {
                    "properties": {
                        "sheetId": sheet_id,
                        "title": new_title
                    },
                    "fields": "title"
                }
            })
        
        response = sheets_service.spreadsheets().batchUpdate(
            spreadsheetId=spreadsheet_id,
            body={"requests": requests}
        ).execute()
        
        updated_names = []
        for reply in response.get("replies", []):
            if "updateSheetProperties" in reply:
                updated_names.append(reply["updateSheetProperties"]["properties"]["title"])
        
        return updated_names
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden of behavioral disclosure. 'Update' implies a mutation, but the description doesn't specify permissions required, whether changes are reversible, error handling (e.g., for invalid sheet names), or rate limits. It lacks critical context for a write operation in a collaborative environment like Google Sheets.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, efficient sentence with zero wasted words. It's front-loaded with the core action and resource, making it easy to parse quickly. Every word earns its place by directly conveying the tool's purpose.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the complexity (a mutation tool with 3 parameters) and the presence of an output schema (which handles return values), the description is minimally adequate. However, with no annotations and incomplete behavioral context, it leaves gaps in understanding permissions, error cases, and operational constraints that are important for safe use.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, with clear descriptions for all three parameters (spreadsheet_name, sheet_names, new_titles). The description adds no additional parameter semantics beyond what the schema provides, such as format details or constraints, so it meets the baseline for high schema coverage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action ('Update') and resource ('sheet titles in a Google Spreadsheet'), making the purpose immediately understandable. It doesn't explicitly differentiate from sibling tools like 'update_spreadsheet_title_tool' or 'update_table_title_tool', but the specificity of 'sheet titles' versus 'spreadsheet title' or 'table title' provides some implicit distinction.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides no guidance on when to use this tool versus alternatives. It doesn't mention prerequisites (e.g., needing an existing spreadsheet), exclusions, or comparisons to sibling tools like 'update_spreadsheet_title_tool' or 'update_table_title_tool', leaving the agent to infer usage from context alone.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/henilcalagiya/google-sheets-mcp'

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