godot_screenshot
Capture screenshots from Godot projects by running them briefly and saving the last rendered frame as an image file.
Instructions
Run a Godot project or specific scene for a short duration, keep the last rendered frame, and return the screenshot path.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| project_path | Yes | Path to the Godot project directory or its project.godot file. | |
| scene_path | No | Optional scene to run instead of the project's configured main scene. | |
| capture_seconds | No | How long to let the project run before selecting the last rendered frame as the screenshot. | |
| fps | No | Movie-capture framerate used to determine which frame to keep. | |
| godot_executable | No | Optional explicit path to the Godot executable or .app bundle. |
Implementation Reference
- src/godot_mcp/godot.py:2089-2200 (handler)The 'screenshot' method in the GodotController class implements the screenshot functionality by launching Godot with the '--write-movie' flag to capture frames, saving the final frame, and returning the screenshot path.
def screenshot( self, project_path: str, scene_path: str | None = None, capture_seconds: float = 2.0, fps: int = 60, godot_executable: str | None = None, ) -> dict[str, Any]: project_dir = ensure_project_path(project_path) executable, version = resolve_godot_executable(godot_executable) if capture_seconds <= 0: raise GodotError("`capture_seconds` must be greater than 0.") if fps < 1: raise GodotError("`fps` must be at least 1.") absolute_scene_path: Path | None = None resource_scene_path: str | None = None run_target = "project" scene_label = "project" command = [ str(executable), "--path", str(project_dir), "--windowed", "--fixed-fps", str(fps), "--disable-vsync", ] if scene_path: absolute_scene_path, resource_scene_path = resolve_scene_path(project_dir, scene_path) if not absolute_scene_path.exists(): raise GodotError(f"Scene not found: {absolute_scene_path}") relative_scene_path = absolute_scene_path.relative_to(project_dir).as_posix() command.extend(["--scene", relative_scene_path]) run_target = "scene" scene_label = absolute_scene_path.stem frame_count = max(1, int(round(capture_seconds * fps))) actual_capture_seconds = frame_count / float(fps) screenshots_dir = project_dir / ".godot-mcp" / "screenshots" screenshots_dir.mkdir(parents=True, exist_ok=True) timestamp = time.strftime("%Y%m%d-%H%M%S") stem = f"{timestamp}-{run_target}-{snake_case_name(scene_label, default=run_target)}" movie_output_path = screenshots_dir / f"{stem}.png" final_screenshot_path = screenshots_dir / f"{stem}-screenshot.png" log_path = _create_log_path(project_dir, "screenshot") command_with_capture = [ command[0], "--log-file", str(log_path), *command[1:], "--write-movie", str(movie_output_path), "--quit-after", str(frame_count), ] timeout_seconds = max(60, int(actual_capture_seconds * 20) + 30) result = subprocess.run( command_with_capture, cwd=project_dir, check=False, capture_output=True, text=True, timeout=timeout_seconds, ) frame_files = sorted(screenshots_dir.glob(f"{stem}" + "[0-9]" * 8 + ".png")) if not frame_files and movie_output_path.exists(): frame_files = [movie_output_path] if result.returncode != 0 or not frame_files: details = "\n".join(part for part in [result.stdout.strip(), result.stderr.strip()] if part).strip() raise GodotError( "Failed to capture a Godot screenshot.\n" f"Log file: {log_path}\n" f"{details or 'No output was returned.'}" ) final_frame = frame_files[-1] if final_screenshot_path.exists(): final_screenshot_path.unlink() final_frame.replace(final_screenshot_path) for frame_path in frame_files[:-1]: frame_path.unlink(missing_ok=True) movie_output_path.unlink(missing_ok=True) (screenshots_dir / f"{stem}.wav").unlink(missing_ok=True) return { "project_path": str(project_dir), "scene_path": str(absolute_scene_path) if absolute_scene_path is not None else None, "scene_resource_path": resource_scene_path, "run_target": run_target, "capture_seconds": actual_capture_seconds, "requested_capture_seconds": capture_seconds, "fps": fps, "frame_count": frame_count, "frame_index": frame_count - 1, "screenshot_path": str(final_screenshot_path), "image_format": "png", "size_bytes": final_screenshot_path.stat().st_size, "command": command_with_capture, "log_path": str(log_path), "godot_executable": str(executable), "godot_version": version, } - src/godot_mcp/server.py:938-977 (registration)The 'godot_screenshot' tool is registered in the GodotMcpServer class, mapping the tool to the controller's screenshot method.
name="godot_screenshot", description="Run a Godot project or specific scene for a short duration, keep the last rendered frame, and return the screenshot path.", input_schema={ "type": "object", "properties": { "project_path": { "type": "string", "description": "Path to the Godot project directory or its project.godot file.", }, "scene_path": { "type": "string", "description": "Optional scene to run instead of the project's configured main scene.", }, "capture_seconds": { "type": "number", "description": "How long to let the project run before selecting the last rendered frame as the screenshot.", "default": 2.0, }, "fps": { "type": "integer", "description": "Movie-capture framerate used to determine which frame to keep.", "default": 60, "minimum": 1, }, "godot_executable": { "type": "string", "description": "Optional explicit path to the Godot executable or .app bundle.", }, }, "required": ["project_path"], "additionalProperties": False, }, handler=lambda args: self.controller.screenshot( project_path=args["project_path"], scene_path=args.get("scene_path"), capture_seconds=float(args.get("capture_seconds", 2.0)), fps=int(args.get("fps", 60)), godot_executable=args.get("godot_executable"), ), ),