Skip to main content
Glama

delete_sheets_tool

Remove specific sheets from a Google Spreadsheet by name to organize and manage spreadsheet content.

Instructions

Delete sheets from a Google Spreadsheet.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
spreadsheet_nameYesThe name of the Google Spreadsheet
sheet_namesYesList of sheet names to delete

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
resultYes

Implementation Reference

  • Main handler function executing the tool logic: validates inputs, checks for last sheet deletion safety, resolves sheet IDs, performs batch delete via Google Sheets API, handles non-existent sheets, and returns JSON response.
    def delete_sheets_handler(
        drive_service,
        sheets_service,
        spreadsheet_name: str,
        sheet_names: List[str]
    ) -> str:
        """Handler to delete sheets from a spreadsheet by their names."""
        
        # Validate input
        if not sheet_names:
            return compact_json_response({
                "success": False,
                "message": "No sheet names 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."
            })
        
        # Check if deleting would leave no sheets
        safety_check = check_last_sheet_deletion(sheets_service, spreadsheet_id, sheet_names)
        if safety_check["would_delete_all"]:
            return compact_json_response({
                "success": False,
                "message": safety_check["error"],
                "total_sheets": safety_check["total_sheets"],
                "sheets_to_delete": safety_check["sheets_to_delete"]
            })
        
        # Get sheet IDs from sheet names
        sheet_id_map = get_sheet_ids_by_names(sheets_service, spreadsheet_id, sheet_names)
        
        # Filter out sheets that don't exist
        existing_sheet_ids = []
        existing_sheet_names = []
        non_existent_sheets = []
        
        for sheet_name in sheet_names:
            sheet_id = sheet_id_map.get(sheet_name)
            if sheet_id is not None:
                existing_sheet_ids.append(sheet_id)
                existing_sheet_names.append(sheet_name)
            else:
                non_existent_sheets.append(sheet_name)
        
        if not existing_sheet_ids:
            return compact_json_response({
                "success": False,
                "message": "No valid sheets found to delete."
            })
        
        try:
            # Delete the sheets
            deleted_ids = delete_sheets(sheets_service, spreadsheet_id, existing_sheet_ids)
            
            response = {
                "success": True,
                "spreadsheet_name": spreadsheet_name,
                "deleted_sheet_names": existing_sheet_names,
                "sheets_deleted": len(deleted_ids),
                "message": f"Successfully deleted {len(deleted_ids)} sheet(s) from '{spreadsheet_name}'"
            }
            
            # Add information about non-existent sheets
            if non_existent_sheets:
                response["non_existent_sheets"] = non_existent_sheets
                response["message"] += f" (Skipped {len(non_existent_sheets)} non-existent sheet(s))"
            
            # Add safety check information
            if "remaining_sheets" in safety_check:
                response["remaining_sheets"] = safety_check["remaining_sheets"]
            
            # Add warning if there was a warning during safety check
            if "warning" in safety_check:
                response["warning"] = safety_check["warning"]
            
            return compact_json_response(response)
            
        except Exception as e:
            return compact_json_response({
                "success": False,
                "message": f"Error deleting sheets: {str(e)}"
            }) 
  • MCP tool registration using @mcp.tool() decorator for 'delete_sheets_tool', including Pydantic input schema (Field definitions) and thin wrapper calling the handler.
    @mcp.tool()
    def delete_sheets_tool(
        spreadsheet_name: str = Field(..., description="The name of the Google Spreadsheet"),
        sheet_names: List[str] = Field(..., description="List of sheet names to delete")
    ) -> str:
        """
        Delete sheets from a Google Spreadsheet.
        """
        sheets_service, drive_service = _get_google_services()
        return delete_sheets_handler(drive_service, sheets_service, spreadsheet_name, sheet_names)
  • Helper function to execute batch delete sheet requests using Google Sheets API batchUpdate.
    def delete_sheets(sheets_service, spreadsheet_id: str, sheet_ids: List[int]) -> List[int]:
        requests = [
            {"deleteSheet": {"sheetId": sheet_id}} for sheet_id in sheet_ids
        ]
        if not requests:
            return []
        try:
            sheets_service.spreadsheets().batchUpdate(
                spreadsheetId=spreadsheet_id,
                body={"requests": requests}
            ).execute()
        except HttpError as error:
            raise RuntimeError(f"Error deleting sheets: {error}")
        return sheet_ids
  • Helper function performing safety check to prevent deletion of all sheets in a spreadsheet (Google Sheets requires at least one sheet).
    def check_last_sheet_deletion(sheets_service, spreadsheet_id: str, sheets_to_delete: List[str]) -> Dict[str, Any]:
        """
        Check if deleting the specified sheets would leave the spreadsheet with no sheets.
        
        Args:
            sheets_service: Google Sheets service
            spreadsheet_id: ID of the spreadsheet
            sheets_to_delete: List of sheet names to be deleted
        
        Returns:
            Dictionary with safety check results
        """
        try:
            result = sheets_service.spreadsheets().get(
                spreadsheetId=spreadsheet_id,
                fields="sheets.properties"
            ).execute()
            
            all_sheets = result.get("sheets", [])
            total_sheets = len(all_sheets)
            sheets_to_delete_set = set(sheets_to_delete)
            
            # Count how many sheets would remain after deletion
            remaining_sheets = 0
            for sheet in all_sheets:
                props = sheet.get("properties", {})
                sheet_name = props.get("title", "")
                if sheet_name not in sheets_to_delete_set:
                    remaining_sheets += 1
            
            if remaining_sheets == 0:
                return {
                    "would_delete_all": True,
                    "total_sheets": total_sheets,
                    "sheets_to_delete": len(sheets_to_delete),
                    "error": f"Cannot delete all sheets. Spreadsheet must have at least one sheet."
                }
            
            return {
                "would_delete_all": False,
                "total_sheets": total_sheets,
                "remaining_sheets": remaining_sheets,
                "sheets_to_delete": len(sheets_to_delete)
            }
            
        except Exception as e:
            # If we can't check, proceed with warning
            return {
                "would_delete_all": False,
                "warning": f"Could not verify sheet count: {str(e)}"
            }
Behavior2/5

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

With no annotations provided, the description carries the full burden of behavioral disclosure. It states the destructive action ('Delete') but lacks critical details: whether deletion is permanent or reversible, what permissions are required, how errors are handled (e.g., if a sheet doesn't exist), or any rate limits. This leaves significant gaps for safe and effective use.

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, direct sentence with zero wasted words. It is front-loaded with the core action and resource, making it highly efficient and easy to parse at a glance.

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

Completeness2/5

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

Given this is a destructive tool with no annotations, the description is incomplete. It lacks behavioral context (e.g., permanence, permissions) and doesn't leverage the output schema to clarify results. For a deletion operation, more guidance on risks and outcomes is needed beyond the basic purpose.

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 both parameters clearly documented in the schema. The description adds no additional semantic context beyond implying the parameters (spreadsheet and sheet names). This meets the baseline of 3 since the schema adequately covers parameter details.

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 ('Delete') and resource ('sheets from a Google Spreadsheet'), making the purpose immediately understandable. It doesn't explicitly differentiate from sibling tools like 'delete_table_tool' or 'delete_table_records_tool', which target different resources, but the specificity is sufficient for basic understanding.

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 (e.g., not deleting all sheets), or compare it to related deletion tools like 'delete_table_tool' or 'delete_table_records_tool'.

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