Skip to main content
Glama
hyunjae-labs

xlwings Excel MCP Server

by hyunjae-labs

delete_range

Remove a specific range of cells in an Excel sheet and shift remaining cells to fill the gap, supporting up or down direction. Integrates with xlwings Excel MCP Server for secure file manipulation in corporate environments.

Instructions

Delete a range of cells and shift remaining cells.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
end_cellYes
filepathYes
sheet_nameYes
shift_directionNoup
start_cellYes

Implementation Reference

  • MCP tool registration and primary handler for 'delete_range'. Dispatches to session-based or legacy implementations based on parameters provided.
    @mcp.tool() def delete_range( sheet_name: str, start_cell: str, end_cell: str, session_id: Optional[str] = None, filepath: Optional[str] = None, shift_direction: str = "up" ) -> str: """ Delete a range of cells and shift remaining cells. Args: sheet_name: Name of worksheet start_cell: Starting cell end_cell: Ending cell session_id: Session ID from open_workbook (preferred) filepath: Path to Excel file (legacy, deprecated) shift_direction: Direction to shift cells ("up" or "left") Note: Use session_id for better performance. filepath parameter is deprecated. """ try: # Support both new (session_id) and old (filepath) API if session_id: # New API: use session session = SESSION_MANAGER.get_session(session_id) if not session: return ERROR_TEMPLATES['SESSION_NOT_FOUND'].format( session_id=session_id, ttl=10 # Default TTL is 10 minutes (600 seconds) ) with session.lock: from xlwings_mcp.xlwings_impl.range_xlw import delete_range_xlw_with_wb result = delete_range_xlw_with_wb( session.workbook, sheet_name, start_cell, end_cell, shift_direction ) elif filepath: # Legacy API: backwards compatibility logger.warning("Using deprecated filepath parameter. Please use session_id instead.") full_path = get_excel_path(filepath) from xlwings_mcp.xlwings_impl.range_xlw import delete_range_xlw result = delete_range_xlw( full_path, sheet_name, start_cell, end_cell, shift_direction ) else: return ERROR_TEMPLATES['PARAMETER_MISSING'].format( param1='session_id', param2='filepath' ) return result.get("message", "Range deleted successfully") if "error" not in result else f"Error: {result['error']}" except (ValidationError, SheetError) as e: return f"Error: {str(e)}" except Exception as e: logger.error(f"Error deleting range: {e}") raise
  • Core xlwings implementation for deleting a cell range (legacy filepath mode). Handles Excel app/workbook lifecycle, validation, deletion with shift, and error handling.
    def delete_range_xlw( filepath: str, sheet_name: str, start_cell: str, end_cell: str, shift_direction: str = "up" ) -> Dict[str, Any]: """ Delete a range of cells and shift remaining cells using xlwings. Args: filepath: Path to Excel file sheet_name: Name of worksheet start_cell: Top-left cell of range to delete end_cell: Bottom-right cell of range to delete shift_direction: Direction to shift cells ("up" or "left") Returns: Dict with success message or error """ app = None wb = None # Initialize COM for thread safety (Windows) _com_initialize() try: logger.info(f"Deleting range {start_cell}:{end_cell} in {sheet_name}, shift {shift_direction}") # Validate shift direction if shift_direction not in ["up", "left"]: return {"error": f"Invalid shift direction: {shift_direction}. Must be 'up' or 'left'"} # Check if file exists if not os.path.exists(filepath): return {"error": f"File not found: {filepath}"} # Open Excel app and workbook app = xw.App(visible=False, add_book=False) wb = app.books.open(filepath) # Check if sheet exists sheet_names = [s.name for s in wb.sheets] if sheet_name not in sheet_names: return {"error": f"Sheet '{sheet_name}' not found"} sheet = wb.sheets[sheet_name] # Get the range to delete delete_range = sheet.range(f"{start_cell}:{end_cell}") # Delete and shift cells if shift_direction == "up": # Shift cells up (xlShiftUp = -4162) delete_range.api.Delete(Shift=-4162) else: # shift_direction == "left" # Shift cells left (xlShiftToLeft = -4159) delete_range.api.Delete(Shift=-4159) # Save the workbook wb.save() logger.info(f"βœ… Successfully deleted range {start_cell}:{end_cell}") return { "message": f"Successfully deleted range {start_cell}:{end_cell} and shifted cells {shift_direction}", "deleted_range": f"{start_cell}:{end_cell}", "shift_direction": shift_direction, "sheet": sheet_name } except Exception as e: logger.error(f"❌ Error deleting range: {str(e)}") return {"error": str(e)} finally: if wb: wb.close() if app: app.quit()
  • Session-optimized helper for deleting cell range using pre-opened workbook. Used by primary handler in session mode.
    def delete_range_xlw_with_wb( wb, sheet_name: str, start_cell: str, end_cell: str, shift_direction: str = "up" ) -> Dict[str, Any]: """ Session-based range deletion using existing workbook object. Args: wb: Workbook object from session sheet_name: Name of worksheet start_cell: Top-left cell of range to delete end_cell: Bottom-right cell of range to delete shift_direction: Direction to shift cells ("up" or "left") Returns: Dict with success message or error """ try: logger.info(f"πŸ—‘οΈ Deleting range {start_cell}:{end_cell} in {sheet_name}, shift {shift_direction}") # Validate shift direction if shift_direction not in ["up", "left"]: return {"error": f"Invalid shift direction: {shift_direction}. Must be 'up' or 'left'"} # Check if sheet exists sheet_names = [s.name for s in wb.sheets] if sheet_name not in sheet_names: return {"error": f"Sheet '{sheet_name}' not found"} sheet = wb.sheets[sheet_name] # Get the range to delete delete_range = sheet.range(f"{start_cell}:{end_cell}") # Delete and shift cells if shift_direction == "up": # Shift cells up (xlShiftUp = -4162) delete_range.api.Delete(Shift=-4162) else: # shift_direction == "left" # Shift cells left (xlShiftToLeft = -4159) delete_range.api.Delete(Shift=-4159) # Save the workbook wb.save() logger.info(f"βœ… Successfully deleted range {start_cell}:{end_cell}") return { "message": f"Successfully deleted range {start_cell}:{end_cell} and shifted cells {shift_direction}", "deleted_range": f"{start_cell}:{end_cell}", "shift_direction": shift_direction, "sheet": sheet_name } except Exception as e: logger.error(f"❌ Error deleting range: {str(e)}") return {"error": str(e)}
  • Legacy wrapper/operation in sheet module that calls the core delete_range_xlw (not directly used by MCP tool).
    def delete_range_operation( filepath: str, sheet_name: str, start_cell: str, end_cell: str, shift_direction: str ) -> Dict[str, Any]: """Delete a range of cells and shift remaining cells.""" result = delete_range_xlw(filepath, sheet_name, start_cell, end_cell, shift_direction) if "error" in result: raise SheetError(result["error"]) return result

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/hyunjae-labs/xlwings-mcp-server'

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