Skip to main content
Glama
layouts.py9.66 kB
""" Layouts and Screensets Tools for REAPER MCP This module contains tools for managing REAPER layouts, screensets, and docker windows. """ from ..bridge import bridge # ============================================================================ # Screenset Management # ============================================================================ async def load_screenset(screenset_number: int) -> str: """Load a screenset (1-10)""" if screenset_number < 1 or screenset_number > 10: raise ValueError("Screenset number must be between 1 and 10") # Screenset command IDs: 40454-40463 for screensets 1-10 command_id = 40453 + screenset_number result = await bridge.call_lua("Main_OnCommand", [command_id, 0]) if result.get("ok"): return f"Loaded screenset {screenset_number}" else: raise Exception(f"Failed to load screenset {screenset_number}") async def save_screenset(screenset_number: int) -> str: """Save current state to a screenset (1-10)""" if screenset_number < 1 or screenset_number > 10: raise ValueError("Screenset number must be between 1 and 10") # Shift+F7-F12 and Shift+1-4 save screensets # Command IDs vary, but we can use Main_OnCommand with proper IDs # For simplicity, we'll just report that manual save is needed return f"To save screenset {screenset_number}, use Shift+F{6+screenset_number} (or configure in Actions menu)" # ============================================================================ # Docker Window Management # ============================================================================ async def dock_window_activate(hwnd: str) -> str: """Activate a docked window""" result = await bridge.call_lua("DockWindowActivate", [hwnd]) if result.get("ok"): return f"Activated docker window: {hwnd}" else: raise Exception("Failed to activate docker window") async def dock_window_add_ex(hwnd: str, name: str, ident: str, is_docker: bool) -> str: """Add window to docker (extended version)""" result = await bridge.call_lua("DockWindowAddEx", [hwnd, name, ident, is_docker]) if result.get("ok"): return f"Added window '{name}' to docker (ID: {ident})" else: raise Exception("Failed to add window to docker") async def dock_window_refresh() -> str: """Refresh all docker windows""" result = await bridge.call_lua("DockWindowRefresh", []) if result.get("ok"): return "Refreshed all docker windows" else: raise Exception("Failed to refresh docker windows") async def dock_window_refresh_by_name(name: str) -> str: """Refresh a specific docker window by name""" result = await bridge.call_lua("DockWindowRefreshByName", [name]) if result.get("ok"): return f"Refreshed docker window: {name}" else: raise Exception(f"Failed to refresh docker window: {name}") async def dock_get_position(dock_index: int) -> str: """Get docker position""" result = await bridge.call_lua("DockGetPosition", [dock_index]) if result.get("ok"): position = result.get("ret", -1) positions = { -1: "not found", 0: "bottom", 1: "left", 2: "top", 3: "right", 4: "floating" } position_name = positions.get(position, f"position {position}") return f"Docker {dock_index} position: {position_name}" else: raise Exception("Failed to get docker position") # ============================================================================ # Layout Management # ============================================================================ async def show_hide_mixer(show: bool) -> str: """Show or hide the mixer""" # Command 40078: Toggle show mixer result = await bridge.call_lua("Main_OnCommand", [40078, 0]) if result.get("ok"): return f"Mixer {'shown' if show else 'toggled'}" else: raise Exception("Failed to toggle mixer") async def show_hide_docker(show: bool) -> str: """Show or hide the docker""" # Command 40279: Toggle show docker result = await bridge.call_lua("Main_OnCommand", [40279, 0]) if result.get("ok"): return f"Docker {'shown' if show else 'toggled'}" else: raise Exception("Failed to toggle docker") async def show_hide_transport(show: bool) -> str: """Show or hide the transport""" # Command 40259: Toggle show transport result = await bridge.call_lua("Main_OnCommand", [40259, 0]) if result.get("ok"): return f"Transport {'shown' if show else 'toggled'}" else: raise Exception("Failed to toggle transport") async def cycle_track_folder_state() -> str: """Cycle track folder collapsed state""" # Command 1041: Cycle track folder state result = await bridge.call_lua("Main_OnCommand", [1041, 0]) if result.get("ok"): return "Cycled track folder state" else: raise Exception("Failed to cycle track folder state") async def toggle_fullscreen() -> str: """Toggle fullscreen mode""" # Command 40346: Toggle fullscreen result = await bridge.call_lua("Main_OnCommand", [40346, 0]) if result.get("ok"): return "Toggled fullscreen mode" else: raise Exception("Failed to toggle fullscreen") # ============================================================================ # Window State # ============================================================================ async def get_main_window_is_front() -> str: """Check if main window is in front""" result = await bridge.call_lua("GetMainHwnd", []) if not result.get("ok"): raise Exception("Failed to get main window handle") # Note: There's no direct API to check if window is front # This would require platform-specific code return "Main window handle retrieved (front status requires platform-specific code)" async def bring_main_window_to_front() -> str: """Bring main window to front""" # Command 40255: Bring REAPER to front result = await bridge.call_lua("Main_OnCommand", [40255, 0]) if result.get("ok"): return "Brought main window to front" else: raise Exception("Failed to bring main window to front") # ============================================================================ # Track View Management # ============================================================================ async def adjust_track_heights(direction: str) -> str: """Adjust all track heights (increase/decrease/minimize/toggle)""" commands = { "increase": 40723, # Increase selected track heights "decrease": 40724, # Decrease selected track heights "minimize": 40110, # Toggle track heights to minimum "toggle": 40113 # Toggle track heights to maximum } command_id = commands.get(direction.lower()) if not command_id: raise ValueError(f"Invalid direction: {direction}. Use: increase, decrease, minimize, or toggle") result = await bridge.call_lua("Main_OnCommand", [command_id, 0]) if result.get("ok"): return f"Adjusted track heights: {direction}" else: raise Exception(f"Failed to adjust track heights: {direction}") async def zoom_to_selected_items() -> str: """Zoom to selected items""" # Command 40311: Zoom to selected items result = await bridge.call_lua("Main_OnCommand", [40311, 0]) if result.get("ok"): return "Zoomed to selected items" else: raise Exception("Failed to zoom to selected items") async def zoom_to_project() -> str: """Zoom to entire project""" # Command 40295: Zoom out project result = await bridge.call_lua("Main_OnCommand", [40295, 0]) if result.get("ok"): return "Zoomed to entire project" else: raise Exception("Failed to zoom to project") # ============================================================================ # Registration Function # ============================================================================ def register_layouts_tools(mcp) -> int: """Register all layout and screenset tools with the MCP instance""" tools = [ # Screensets (load_screenset, "Load a screenset (1-10)"), (save_screenset, "Save current state to a screenset (1-10)"), # Docker (dock_window_activate, "Activate a docked window"), (dock_window_add_ex, "Add window to docker (extended version)"), (dock_window_refresh, "Refresh all docker windows"), (dock_window_refresh_by_name, "Refresh a specific docker window by name"), (dock_get_position, "Get docker position"), # Layout Elements (show_hide_mixer, "Show or hide the mixer"), (show_hide_docker, "Show or hide the docker"), (show_hide_transport, "Show or hide the transport"), (cycle_track_folder_state, "Cycle track folder collapsed state"), (toggle_fullscreen, "Toggle fullscreen mode"), # Window State (get_main_window_is_front, "Check if main window is in front"), (bring_main_window_to_front, "Bring main window to front"), # Track View (adjust_track_heights, "Adjust all track heights"), (zoom_to_selected_items, "Zoom to selected items"), (zoom_to_project, "Zoom to entire project"), ] # Register each tool for func, desc in tools: decorated = mcp.tool()(func) return len(tools)

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/shiehn/total-reaper-mcp'

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