render_time_selection
Render a specified time range of a REAPER project to an audio file with configurable format, sample rate, bit depth, and channels.
Instructions
Render a specific time range of the project to a file.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| output_path | Yes | ||
| start | Yes | ||
| end | Yes | ||
| format | No | wav | |
| sample_rate | No | ||
| bit_depth | No | ||
| channels | No |
Implementation Reference
- src/reaper_mcp/render_tools.py:96-125 (handler)The `render_time_selection` function - the actual tool logic that sets time selection, configures render settings with bounds=1, and invokes REAPER's render command.
@mcp.tool() def render_time_selection( output_path: str, start: float, end: float, format: str = "wav", sample_rate: int = 48000, bit_depth: int = 24, channels: int = 2, ) -> dict: """Render a specific time range of the project to a file.""" try: output_path = str(Path(output_path).expanduser().resolve()) os.makedirs(os.path.dirname(output_path), exist_ok=True) project = get_project() project.time_selection = (start, end) _set_render_settings(output_path, format, sample_rate, bit_depth, channels, bounds=1) RPR.Main_OnCommand(41824, 0) if not os.path.exists(output_path): return {"success": False, "error": "Render completed but output file not found"} return { "success": True, "output_path": output_path, "start": start, "end": end, "format": format, "file_size_bytes": os.path.getsize(output_path), } except Exception as e: return {"success": False, "error": str(e)} - The function signature/type annotations serve as the schema: accepts output_path (str), start (float), end (float), format (str default 'wav'), sample_rate (int), bit_depth (int), channels (int), returns dict.
@mcp.tool() def render_time_selection( output_path: str, start: float, end: float, format: str = "wav", sample_rate: int = 48000, bit_depth: int = 24, channels: int = 2, ) -> dict: """Render a specific time range of the project to a file.""" try: output_path = str(Path(output_path).expanduser().resolve()) os.makedirs(os.path.dirname(output_path), exist_ok=True) project = get_project() project.time_selection = (start, end) _set_render_settings(output_path, format, sample_rate, bit_depth, channels, bounds=1) RPR.Main_OnCommand(41824, 0) if not os.path.exists(output_path): return {"success": False, "error": "Render completed but output file not found"} return { "success": True, "output_path": output_path, "start": start, "end": end, "format": format, "file_size_bytes": os.path.getsize(output_path), } except Exception as e: return {"success": False, "error": str(e)} - src/reaper_mcp/render_tools.py:59-125 (registration)The tool is registered via the `@mcp.tool()` decorator inside `register_tools(mcp)` which is called from server.py line 26.
def register_tools(mcp): @mcp.tool() def render_project( output_path: str, format: str = "wav", sample_rate: int = 48000, bit_depth: int = 24, channels: int = 2, ) -> dict: """ Render the entire project to a file. format: wav, flac, mp3 (requires LAME), ogg. sample_rate: e.g. 44100, 48000, 96000. bit_depth: 16, 24, or 32 (WAV only; ignored for mp3/ogg/flac). channels: 1 (mono) or 2 (stereo). """ try: output_path = str(Path(output_path).expanduser().resolve()) os.makedirs(os.path.dirname(output_path), exist_ok=True) _set_render_settings(output_path, format, sample_rate, bit_depth, channels, bounds=0) RPR.Main_OnCommand(41824, 0) # File: Render project to disk (no dialog) if not os.path.exists(output_path): return {"success": False, "error": "Render command completed but output file not found"} return { "success": True, "output_path": output_path, "format": format, "sample_rate": sample_rate, "bit_depth": bit_depth, "channels": channels, "file_size_bytes": os.path.getsize(output_path), } except Exception as e: logger.error(f"render_project failed: {e}") return {"success": False, "error": str(e)} @mcp.tool() def render_time_selection( output_path: str, start: float, end: float, format: str = "wav", sample_rate: int = 48000, bit_depth: int = 24, channels: int = 2, ) -> dict: """Render a specific time range of the project to a file.""" try: output_path = str(Path(output_path).expanduser().resolve()) os.makedirs(os.path.dirname(output_path), exist_ok=True) project = get_project() project.time_selection = (start, end) _set_render_settings(output_path, format, sample_rate, bit_depth, channels, bounds=1) RPR.Main_OnCommand(41824, 0) if not os.path.exists(output_path): return {"success": False, "error": "Render completed but output file not found"} return { "success": True, "output_path": output_path, "start": start, "end": end, "format": format, "file_size_bytes": os.path.getsize(output_path), } except Exception as e: return {"success": False, "error": str(e)} - src/reaper_mcp/render_tools.py:28-44 (helper)The `_set_render_settings` helper configures REAPER's render parameters (output path, format, sample rate, bit depth, channels, bounds flag) via the REAPER API.
def _set_render_settings( output_path: str, format: str, sample_rate: int, bit_depth: int, channels: int, bounds: int, ) -> None: """Configure REAPER's render settings. bounds: 0=entire project, 1=time selection.""" fmt_code = FORMAT_CODES.get(format.lower(), 0) bdepth_code = BIT_DEPTH_CODES.get(bit_depth, 2) RPR.GetSetProjectInfo_String(0, "RENDER_FILE", output_path, True) RPR.GetSetProjectInfo(0, "RENDER_FORMAT", fmt_code, True) RPR.GetSetProjectInfo(0, "RENDER_FORMAT2", bdepth_code, True) RPR.GetSetProjectInfo(0, "RENDER_SRATE", float(sample_rate), True) RPR.GetSetProjectInfo(0, "RENDER_CHANNELS", float(channels), True) RPR.GetSetProjectInfo(0, "RENDER_BOUNDSFLAG", float(bounds), True) - src/reaper_mcp/connection.py:27-29 (helper)The `get_project()` helper returns the current REAPER project object via reapy, used to set the time selection on the project.
def get_project() -> reapy.Project: ensure_connected() return reapy.Project()