We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/ShirshovDIM/retopoflow_blender_mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server
"""
Viewport Control Tools
Tools for controlling viewport projection, navigation, and view alignment.
"""
from mcp.server.fastmcp import Context
import logging
logger = logging.getLogger("BlenderMCPServer")
def set_view_projection(
ctx: Context,
blender_connection,
projection: str = "ORTHO"
) -> str:
"""
Toggle viewport projection between orthographic and perspective.
Parameters:
- projection: "ORTHO" for orthographic or "PERSP" for perspective (default: "ORTHO")
Orthographic: No perspective foreshortening, parallel lines stay parallel.
Perspective: Realistic depth perspective, objects farther away appear smaller.
"""
try:
result = blender_connection.send_command("set_view_projection", {
"projection": projection
})
if "error" in result:
return f"Error: {result['error']}"
output = f"Viewport Projection Set to {result.get('projection', projection)}!\n\n"
if projection == "ORTHO":
output += "Orthographic mode: No perspective distortion, ideal for precision work.\n"
else:
output += "Perspective mode: Realistic depth perception.\n"
return output
except Exception as e:
logger.error(f"Error setting view projection: {str(e)}")
return f"Error setting view projection: {str(e)}"
def align_view_to_axis(
ctx: Context,
blender_connection,
axis: str,
side: str
) -> str:
"""
Align viewport to a specific global axis and side.
Parameters:
- axis: "X", "Y", or "Z"
- side: "POS" (positive direction) or "NEG" (negative direction)
Mappings:
- Y/POS = FRONT view
- Y/NEG = BACK view
- X/POS = RIGHT view
- X/NEG = LEFT view
- Z/POS = TOP view
- Z/NEG = BOTTOM view
"""
try:
result = blender_connection.send_command("align_view_to_axis", {
"axis": axis,
"side": side
})
if "error" in result:
return f"Error: {result['error']}"
output = f"View Aligned to {result.get('view', 'Unknown')}!\n\n"
output += f"Axis: {result.get('axis', axis)}\n"
output += f"Side: {result.get('side', side)}\n"
return output
except Exception as e:
logger.error(f"Error aligning view: {str(e)}")
return f"Error aligning view: {str(e)}"
def frame_selected(
ctx: Context,
blender_connection
) -> str:
"""
Frame the currently selected objects in the viewport.
The viewport will center on and zoom to fit the selected objects.
No parameters required. Operates on current selection.
"""
try:
result = blender_connection.send_command("frame_selected", {})
if "error" in result:
return f"Error: {result['error']}"
return "Viewport framed to selected objects!"
except Exception as e:
logger.error(f"Error framing selected: {str(e)}")
return f"Error framing selected: {str(e)}"
def focus_view_on_point(
ctx: Context,
blender_connection,
x: float,
y: float,
z: float,
distance: float = None,
view_axis: str = None
) -> str:
"""
Focus viewport on a specific 3D point.
Centers the viewport on the specified coordinates with optional
distance and axis alignment. Essential for navigating to problem
areas identified by analyze_mesh_regions.
Parameters:
- x: X coordinate of the target point
- y: Y coordinate of the target point
- z: Z coordinate of the target point
- distance: Optional viewing distance from target (default: maintain current)
- view_axis: Optional axis alignment - "FRONT", "BACK", "LEFT", "RIGHT", "TOP", "BOTTOM"
Use with analyze_mesh_regions to navigate to problem zones.
"""
try:
params = {"x": x, "y": y, "z": z}
if distance is not None:
params["distance"] = distance
if view_axis is not None:
params["view_axis"] = view_axis
result = blender_connection.send_command("focus_view_on_point", params)
if "error" in result:
return f"Error: {result['error']}"
target = result.get("target", {})
output = f"Viewport focused on point ({target.get('x', x):.3f}, {target.get('y', y):.3f}, {target.get('z', z):.3f})\n"
output += f"View distance: {result.get('view_distance', 'unchanged')}\n"
if view_axis:
output += f"View aligned to: {view_axis}\n"
return output
except Exception as e:
logger.error(f"Error focusing view: {str(e)}")
return f"Error focusing view: {str(e)}"