Skip to main content
Glama

update_table_sorting_tool

Sort data rows in Google Sheets tables by a specific column while keeping headers fixed. Choose ascending or descending order to organize spreadsheet information.

Instructions

Update table sorting by a specific column.

This tool sorts all data rows in a table based on a specified column.
The header row remains in place, and data rows are reordered.

Args:
    spreadsheet_name: Name of the spreadsheet
    sheet_name: Name of the sheet containing the table
    table_name: Name of the table to sort
    column_name: Name of the column to sort by
    sort_order: Sort order - "ASC" or "DESC" (default: "ASC")

Returns:
    JSON string with success status and sorting 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 sort
column_nameYesName of the column to sort by
sort_orderNoSort order: 'ASC' or 'DESC' (default: 'ASC')ASC

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
resultYes

Implementation Reference

  • Core handler function implementing the table sorting logic using Google Sheets API's setBasicFilter for sorting followed by clearBasicFilter to remove the filter after sorting.
    def update_table_sorting_handler(
        drive_service,
        sheets_service,
        spreadsheet_name: str,
        sheet_name: str,
        table_name: str,
        column_name: str,
        sort_order: str = "ASC"
    ) -> str:
        """
        Apply basic filter sorting to a table in Google Sheets and then remove the filter.
        
        This function uses the setBasicFilter request to sort table data using the filter functionality,
        then removes the filter to allow new records to be added.
        
        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 sort
            column_name: Name of the column to sort by
            sort_order: Sort order ("ASC" or "DESC")
        
        Returns:
            str: Success message with sort 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 not column_name or column_name.strip() == "":
                return compact_json_response({
                    "success": False,
                    "message": "Column name is required."
                })
            
            # Validate sort order
            valid_orders = ["ASC", "DESC"]
            if sort_order not in valid_orders:
                return compact_json_response({
                    "success": False,
                    "message": f"Invalid sort order: {sort_order}. Valid orders are: {', '.join(valid_orders)}"
                })
            
            # Convert short names to Google Sheets API values
            api_sort_order = "ASCENDING" if sort_order == "ASC" else "DESCENDING"
            
            # 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)
            except Exception as e:
                return compact_json_response({
                    "success": False,
                    "message": f"Could not retrieve table information: {str(e)}"
                })
            
            # Get table range
            table_range = table_info.get("range", {})
            table_start_row = table_range.get("startRowIndex", 0)
            table_end_row = table_range.get("endRowIndex", 0)
            table_start_col = table_range.get("startColumnIndex", 0)
            table_end_col = table_range.get("endColumnIndex", 0)
            
            # Get table columns
            columns = table_info.get("columns", [])
            column_names = [col.get("name", "") for col in columns]
            
            # Validate sort column exists in table
            if column_name not in column_names:
                return compact_json_response({
                    "success": False,
                    "message": f"Sort column '{column_name}' not found in table. Available columns: {', '.join(column_names)}"
                })
            
            # Find column index
            col_index = column_names.index(column_name)
            
            # Create setBasicFilter request according to official API documentation
            # This applies sorting using the filter functionality
            set_basic_filter_request = {
                "setBasicFilter": {
                    "filter": {
                        "range": {
                            "sheetId": sheet_id,
                            "startRowIndex": table_start_row,
                            "endRowIndex": table_end_row,
                            "startColumnIndex": table_start_col,
                            "endColumnIndex": table_end_col
                        },
                        "sortSpecs": [
                            {
                                "dimensionIndex": col_index,
                                "sortOrder": api_sort_order
                            }
                        ]
                    }
                }
            }
            
            # Create clearBasicFilter request to remove the filter after sorting
            clear_basic_filter_request = {
                "clearBasicFilter": {
                    "sheetId": sheet_id
                }
            }
            
            # Execute both requests: first sort, then remove filter
            try:
                response = sheets_service.spreadsheets().batchUpdate(
                    spreadsheetId=spreadsheet_id,
                    body={"requests": [set_basic_filter_request, clear_basic_filter_request]}
                ).execute()
            except Exception as api_error:
                return compact_json_response({
                    "success": False,
                    "message": f"API call failed: {str(api_error)}"
                })
            
            # Extract response information
            replies = response.get("replies", [])
            
            # Debug: Log the response structure
            print(f"Debug - Response keys: {list(response.keys())}")
            print(f"Debug - Replies: {replies}")
            
            # Check if the request was successful (any reply means success)
            if replies and len(replies) > 0:
                response_data = {
                    "success": True,
                    "spreadsheet_name": spreadsheet_name,
                    "sheet_name": sheet_name,
                    "table_name": table_name,
                    "table_id": table_id,
                    "sort_column": column_name,
                    "sort_order": sort_order,
                    "rows_sorted": table_end_row - table_start_row,
                    "filter_removed": True,
                    "message": f"Successfully sorted table '{table_name}' by '{column_name}' ({sort_order}) and removed filter in '{sheet_name}'"
                }
                
                return compact_json_response(response_data)
            else:
                return compact_json_response({
                    "success": False,
                    "message": "Failed to apply sorting and remove filter - no response data from API"
                })
            
        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 applying sorting and removing filter: {str(e)}"
            }) 
  • MCP tool registration with pydantic schema validation for input parameters. Delegates execution to the handler function.
    @mcp.tool()
    def update_table_sorting_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 sort"),
        column_name: str = Field(..., description="Name of the column to sort by"),
        sort_order: str = Field(default="ASC", description="Sort order: 'ASC' or 'DESC' (default: 'ASC')")
    ) -> str:
        """
        Update table sorting by a specific column.
        
        This tool sorts all data rows in a table based on a specified column.
        The header row remains in place, and data rows are reordered.
        
        Args:
            spreadsheet_name: Name of the spreadsheet
            sheet_name: Name of the sheet containing the table
            table_name: Name of the table to sort
            column_name: Name of the column to sort by
            sort_order: Sort order - "ASC" or "DESC" (default: "ASC")
        
        Returns:
            JSON string with success status and sorting details
        """
        sheets_service, drive_service = _get_google_services()
        return update_table_sorting_handler(drive_service, sheets_service, spreadsheet_name, sheet_name, table_name, column_name, sort_order)
  • Pydantic Field definitions providing input schema, descriptions, and validation for the tool parameters.
    @mcp.tool()
    def update_table_sorting_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 sort"),
        column_name: str = Field(..., description="Name of the column to sort by"),
        sort_order: str = Field(default="ASC", description="Sort order: 'ASC' or 'DESC' (default: 'ASC')")
    ) -> str:
        """
        Update table sorting by a specific column.
        
        This tool sorts all data rows in a table based on a specified column.
        The header row remains in place, and data rows are reordered.
        
        Args:
            spreadsheet_name: Name of the spreadsheet
            sheet_name: Name of the sheet containing the table
            table_name: Name of the table to sort
            column_name: Name of the column to sort by
            sort_order: Sort order - "ASC" or "DESC" (default: "ASC")
        
        Returns:
            JSON string with success status and sorting details
        """
        sheets_service, drive_service = _get_google_services()
        return update_table_sorting_handler(drive_service, sheets_service, spreadsheet_name, sheet_name, table_name, column_name, sort_order)
Behavior3/5

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

With no annotations provided, the description carries full burden. It discloses key behavioral traits: sorts data rows (not header), reorders rows, and returns JSON with success status. However, it lacks details on permissions needed, error conditions (e.g., invalid column names), whether sorting is destructive (overwrites original order), or rate limits. The description adds basic context but misses critical operational details.

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

Conciseness4/5

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

The description is appropriately sized and front-loaded: the first sentence states the purpose, followed by elaboration, then structured 'Args' and 'Returns' sections. It avoids redundancy but could be slightly more concise by integrating the elaboration into the initial statement. Every sentence earns its place by adding clarity.

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 5 parameters, 100% schema coverage, and an output schema (implied by 'Returns'), the description is moderately complete. It covers the basic operation and parameters but lacks context on errors, side effects, or integration with sibling tools. For a mutation tool with no annotations, it should provide more behavioral transparency to be fully helpful.

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%, so parameters are well-documented in the schema. The description adds minimal value beyond the schema: it lists parameters in the 'Args' section but doesn't provide additional semantics like format examples (e.g., case sensitivity for names) or constraints (e.g., column must exist). Baseline 3 is appropriate as the schema does the heavy lifting.

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 tool's purpose: 'Update table sorting by a specific column' and 'sorts all data rows in a table based on a specified column.' It specifies the verb ('update sorting') and resource ('table'), but doesn't explicitly differentiate from siblings like 'update_table_cells_by_range_tool' or 'update_table_column_name_tool' which modify different aspects of tables.

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., table must exist), exclusions (e.g., cannot sort by non-existent columns), or compare to sibling tools like 'get_table_data_tool' (which might retrieve sorted data differently). Usage is implied only through the action described.

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