Skip to main content
Glama

update_dropdown_options_tool

Add or remove dropdown options in Google Sheets table columns to maintain data validation and improve data entry accuracy.

Instructions

Update dropdown options in a table column.

This tool can add or remove specific dropdown options from an existing column in a table.
For 'add' action: Adds new options to existing dropdown (preserves existing options).
For 'remove' action: Removes specific options from existing dropdown.

Args:
    spreadsheet_name: Name of the spreadsheet
    sheet_name: Name of the sheet containing the table
    table_name: Name of the table to update dropdown options in
    action: Action to perform - "add" or "remove"
    column_name: Name of the column to update dropdown options for
    dropdown_options: List of dropdown options to add/remove

Returns:
    JSON string with success status and dropdown update details

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
spreadsheet_nameYesThe name of the Google Spreadsheet
sheet_nameYesThe name of the sheet containing the table
table_nameYesName of the table to update dropdown options in
actionYesAction to perform: 'add' or 'remove'
column_nameYesName of the column to update dropdown options for
dropdown_optionsNoList of dropdown options to add/remove (required for 'add' and 'remove' actions)

Implementation Reference

  • The main handler function that performs input validation, retrieves spreadsheet/sheet/table IDs using helper utilities, constructs Google Sheets API batchUpdate requests to modify column dataValidationRule for DROPDOWN columns (add or remove options), and returns JSON response.
    def update_dropdown_options_handler(
        drive_service,
        sheets_service,
        spreadsheet_name: str,
        sheet_name: str,
        table_name: str,
        action: str,
        column_name: str,
        dropdown_options: Optional[List[str]] = None
    ) -> str:
        """
        Update dropdown options in a table column in Google Sheets using the official updateTable operation.
        
        According to the official Google Sheets API documentation, to update dropdown options:
        1. Use UpdateTableRequest to update column properties with data validation rules
        2. Set the column type to DROPDOWN and add validation options, or remove validation
        
        Args:
            drive_service: Google Drive service instance
            sheets_service: Google Sheets service instance
            spreadsheet_name: Name of the spreadsheet
            sheet_name: Name of the sheet containing the table
            table_name: Name of the table to update dropdown options in
            action: Action to perform - "add" or "remove"
            column_name: Name of the column to update dropdown options for
            dropdown_options: List of dropdown options to add/remove:
                - For "add" action: List of new options to add to existing dropdown
                - For "remove" action: List of options to remove from existing dropdown
        
        Returns:
            str: Success message with dropdown update details or error message
        """
        try:
            # Validate inputs
            if not table_name or table_name.strip() == "":
                return compact_json_response({
                    "success": False,
                    "message": "Table name is required."
                })
            
            if action not in ["add", "remove"]:
                return compact_json_response({
                    "success": False,
                    "message": "Action must be 'add' or 'remove'."
                })
            
            if not column_name or not isinstance(column_name, str) or column_name.strip() == "":
                return compact_json_response({
                    "success": False,
                    "message": "Column name is required and cannot be empty."
                })
            
            # Validate dropdown options for add/remove actions
            if action in ["add", "remove"]:
                if not dropdown_options or not isinstance(dropdown_options, list):
                    return compact_json_response({
                        "success": False,
                        "message": f"Dropdown options are required for '{action}' action and must be a list."
                    })
            
            # Validate column name
            validated_column = column_name.strip()
            
            # Validate dropdown options for add/remove actions
            validated_operations = []
            if action in ["add", "remove"]:
                if not dropdown_options:
                    return compact_json_response({
                        "success": False,
                        "message": f"Dropdown options are required for '{action}' action."
                    })
                
                if not isinstance(dropdown_options, list):
                    return compact_json_response({
                        "success": False,
                        "message": "Dropdown options must be a list."
                    })
                
                if not dropdown_options:
                    return compact_json_response({
                        "success": False,
                        "message": "Dropdown options cannot be empty."
                    })
                
                # Validate individual options
                valid_options = []
                invalid_options = []
                
                for j, option in enumerate(dropdown_options):
                    if not isinstance(option, str) or option.strip() == "":
                        invalid_options.append({"option_index": j, "option": option, "error": "Option cannot be empty"})
                    else:
                        valid_options.append(option.strip())
                
                if invalid_options:
                    error_messages = [f"Option {item['option_index']+1}: {item['error']}" for item in invalid_options]
                    return compact_json_response({
                        "success": False,
                        "message": f"Invalid options: {'; '.join(error_messages)}"
                    })
                
                if not valid_options:
                    return compact_json_response({
                        "success": False,
                        "message": "No valid options provided."
                    })
                
                validated_operations.append({
                    "column_name": validated_column,
                    "options": valid_options
                })
            
            # 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 ID
            sheet_ids = get_sheet_ids_by_names(sheets_service, spreadsheet_id, [sheet_name])
            sheet_id = sheet_ids.get(sheet_name)
            if sheet_id is None:
                return compact_json_response({
                    "success": False,
                    "message": f"Sheet '{sheet_name}' not found in spreadsheet '{spreadsheet_name}'."
                })
            
            # Get table ID
            table_ids = get_table_ids_by_names(sheets_service, spreadsheet_id, sheet_name, [table_name])
            table_id = table_ids.get(table_name)
            if not table_id:
                return compact_json_response({
                    "success": False,
                    "message": f"Table '{table_name}' not found in sheet '{sheet_name}'."
                })
            
            # Get table information
            try:
                table_info = get_table_info(sheets_service, spreadsheet_id, table_id)
                columns = table_info.get('columns', [])
            except Exception as e:
                return compact_json_response({
                    "success": False,
                    "message": f"Could not retrieve information for table '{table_name}': {str(e)}"
                })
            
            # Validate that the specified column exists in the table
            existing_column_names = [col.get("name", "") for col in columns]
            missing_columns = []
            valid_operations = []
            
            if action == "add":
                # For add action, check if column exists
                if validated_column not in existing_column_names:
                    missing_columns.append(validated_column)
                else:
                    valid_operations.append({
                        "column_name": validated_column,
                        "options": dropdown_options
                    })
            elif action == "remove":
                # For remove action, check if column exists and has dropdown validation
                for col in columns:
                    if col.get("name", "") == validated_column:
                        col_type = col.get("type", "TEXT")
                        has_validation = "dataValidationRule" in col
                        
                        if col_type == "DROPDOWN" and has_validation:
                            valid_operations.append({
                                "column_name": validated_column,
                                "options": dropdown_options
                            })
                        else:
                            missing_columns.append(validated_column)
                        break
            
            if missing_columns:
                return compact_json_response({
                    "success": False,
                    "message": f"Column(s) not found or invalid: {', '.join(missing_columns)}"
                })
            
            if not valid_operations:
                return compact_json_response({
                    "success": False,
                    "message": f"No valid {action} operations after validation."
                })
            
            # Create batch update requests
            requests = []
            
            # Update table column properties
            updated_columns = []
            for col in columns:
                col_name = col.get("name", "")
                col_index = col.get("index", 0)
                col_updated = False
                
                if action == "add":
                    # Add dropdown validation or add options to existing dropdown
                    for operation in valid_operations:
                        if operation["column_name"] == col_name:
                            # Get existing dropdown options if any
                            existing_options = []
                            if col.get("type") == "DROPDOWN" and "dataValidationRule" in col:
                                existing_values = col["dataValidationRule"].get("condition", {}).get("values", [])
                                existing_options = [val.get("userEnteredValue", "") for val in existing_values if val.get("userEnteredValue")]
                            
                            # Combine existing and new options, removing duplicates
                            all_options = list(set(existing_options + operation["options"]))
                            
                            updated_col = {
                                "columnIndex": col_index,
                                "columnName": col_name,
                                "columnType": "DROPDOWN",
                                "dataValidationRule": {
                                    "condition": {
                                        "type": "ONE_OF_LIST",
                                        "values": [{"userEnteredValue": opt} for opt in all_options]
                                    }
                                }
                            }
                            updated_columns.append(updated_col)
                            col_updated = True
                            break
                elif action == "remove":
                    # Remove specific options from dropdown
                    for operation in valid_operations:
                        if operation["column_name"] == col_name:
                            # Get existing dropdown options
                            existing_options = []
                            if col.get("type") == "DROPDOWN" and "dataValidationRule" in col:
                                existing_values = col["dataValidationRule"].get("condition", {}).get("values", [])
                                existing_options = [val.get("userEnteredValue", "") for val in existing_values if val.get("userEnteredValue")]
                            
                            # Remove specified options
                            options_to_remove = set(operation["options"])
                            remaining_options = [opt for opt in existing_options if opt not in options_to_remove]
                            
                            if remaining_options:
                                # Keep dropdown with remaining options
                                updated_col = {
                                    "columnIndex": col_index,
                                    "columnName": col_name,
                                    "columnType": "DROPDOWN",
                                    "dataValidationRule": {
                                        "condition": {
                                            "type": "ONE_OF_LIST",
                                            "values": [{"userEnteredValue": opt} for opt in remaining_options]
                                        }
                                    }
                                }
                            else:
                                # Convert to TEXT if no options remain
                                updated_col = {
                                    "columnIndex": col_index,
                                    "columnName": col_name,
                                    "columnType": "TEXT"
                                }
                            
                            updated_columns.append(updated_col)
                            col_updated = True
                            break
                
                if not col_updated:
                    # Keep existing column unchanged - only include required fields
                    updated_col = {
                        "columnIndex": col_index,
                        "columnName": col_name,
                        "columnType": col.get("type", "TEXT")
                    }
                    # Preserve dataValidationRule if it exists
                    if "dataValidationRule" in col:
                        updated_col["dataValidationRule"] = col["dataValidationRule"]
                    updated_columns.append(updated_col)
            
            update_table_request = {
                "updateTable": {
                    "table": {
                        "tableId": table_id,
                        "columnProperties": updated_columns
                    },
                    "fields": "columnProperties.dataValidationRule"
                }
            }
            requests.append(update_table_request)
            
            # Execute the batch update
            response = sheets_service.spreadsheets().batchUpdate(
                spreadsheetId=spreadsheet_id,
                body={"requests": requests}
            ).execute()
            
            # Extract response information
            replies = response.get("replies", [])
            successful_operations = len(valid_operations)
            
            if action == "add":
                response_data = {
                    "success": True,
                    "spreadsheet_name": spreadsheet_name,
                    "sheet_name": sheet_name,
                    "table_name": table_name,
                    "action": "add",
                    "dropdowns_updated": successful_operations,
                    "options_added": valid_operations,
                    "message": f"Successfully added dropdown options to {successful_operations} column(s) in table '{table_name}' in '{sheet_name}'"
                }
            elif action == "remove":
                response_data = {
                    "success": True,
                    "spreadsheet_name": spreadsheet_name,
                    "sheet_name": sheet_name,
                    "table_name": table_name,
                    "action": "remove",
                    "dropdowns_updated": successful_operations,
                    "options_removed": valid_operations,
                    "message": f"Successfully removed dropdown options from {successful_operations} column(s) in table '{table_name}' in '{sheet_name}'"
                }
            
            return compact_json_response(response_data)
            
        except HttpError as error:
            return compact_json_response({
                "success": False,
                "message": f"Google Sheets API error: {str(error)}"
            })
        except Exception as e:
            return compact_json_response({
                "success": False,
                "message": f"Error managing dropdown options: {str(e)}"
            }) 
  • Registers the MCP tool 'update_dropdown_options_tool' with Pydantic input schema using @mcp.tool() decorator. Initializes Google services and delegates execution to the handler function.
    @mcp.tool()
    def update_dropdown_options_tool(
        spreadsheet_name: str = Field(..., description="The name of the Google Spreadsheet"),
        sheet_name: str = Field(..., description="The name of the sheet containing the table"),
        table_name: str = Field(..., description="Name of the table to update dropdown options in"),
        action: str = Field(..., description="Action to perform: 'add' or 'remove'"),
        column_name: str = Field(..., description="Name of the column to update dropdown options for"),
        dropdown_options: List[str] = Field(default=[], description="List of dropdown options to add/remove (required for 'add' and 'remove' actions)")
    ) -> str:
        """
        Update dropdown options in a table column.
        
        This tool can add or remove specific dropdown options from an existing column in a table.
        For 'add' action: Adds new options to existing dropdown (preserves existing options).
        For 'remove' action: Removes specific options from existing dropdown.
        
        Args:
            spreadsheet_name: Name of the spreadsheet
            sheet_name: Name of the sheet containing the table
            table_name: Name of the table to update dropdown options in
            action: Action to perform - "add" or "remove"
            column_name: Name of the column to update dropdown options for
            dropdown_options: List of dropdown options to add/remove
        
        Returns:
            JSON string with success status and dropdown update details
        """
        sheets_service, drive_service = _get_google_services()
        return update_dropdown_options_handler(drive_service, sheets_service, spreadsheet_name, sheet_name, table_name, action, column_name, dropdown_options)
  • Pydantic Field definitions providing the input schema, validation, and descriptions for the tool parameters.
    spreadsheet_name: str = Field(..., description="The name of the Google Spreadsheet"),
    sheet_name: str = Field(..., description="The name of the sheet containing the table"),
    table_name: str = Field(..., description="Name of the table to update dropdown options in"),
    action: str = Field(..., description="Action to perform: 'add' or 'remove'"),
    column_name: str = Field(..., description="Name of the column to update dropdown options for"),
    dropdown_options: List[str] = Field(default=[], description="List of dropdown options to add/remove (required for 'add' and 'remove' actions)")

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