Skip to main content
Glama

robot_virtual

Manage virtual robots in Unity or VRChat by creating, updating, deleting, and operating them. Perform tasks like loading environments, testing navigation, and syncing with physical robots.

Instructions

Virtual robot lifecycle and operations portmanteau.

PORTMANTEAU PATTERN: Consolidates virtual robot CRUD operations and virtual robotics operations into a single unified tool. This reduces tool explosion while maintaining full functionality for virtual robot management.

CRUD OPERATIONS:

  • create: Create/spawn and register a new virtual robot

  • read: Get details of an existing virtual robot

  • update: Modify virtual robot properties (scale, position, metadata, etc.)

  • delete: Remove and unregister a virtual robot

  • list: List all virtual robots with optional filtering

VIRTUAL ROBOT OPERATIONS:

  • spawn: Spawn robot in Unity/VRChat scene (alias for create)

  • load_environment: Load Marble/Chisel environment into scene

  • get_status: Get virtual robot status

  • get_lidar: Get virtual LiDAR scan (Unity physics raycast)

  • set_scale: Scale robot size (for size testing)

  • test_navigation: Test pathfinding in environment

  • sync_with_physical: Sync vbot state with physical bot

Args: operation: Operation to perform (see CRUD and Virtual Robot Operations above). robot_type: Type of robot (required for create/spawn). Examples: "scout", "go2", "g1", "robbie", "custom" robot_id: Virtual robot identifier (required for read, update, delete, get_status, etc.). Auto-generated for create/spawn if not provided. platform: Target platform ("unity" or "vrchat"). Default: "unity". position: Spawn/update position (x, y, z) for create/spawn/update. scale: Size multiplier for create/spawn/update/set_scale. metadata: Additional metadata dictionary for create/update. model_path: Path to 3D model file (.glb, .fbx, .vrm) for custom robot_type. environment: Environment name (Marble-generated) for load_environment. environment_path: Path to environment file for load_environment. project_path: Unity project path (optional, auto-detected if not provided). include_colliders: Whether to import collider meshes (default: True).

Returns: Dictionary containing operation result with robot details.

Examples: # Create a Scout vbot result = await robot_virtual( operation="create", robot_type="scout", platform="unity", position={"x": 0.0, "y": 0.0, "z": 0.0}, scale=1.0 )

# Spawn robot (alias for create) result = await robot_virtual( operation="spawn", robot_type="scout", platform="unity" ) # Read vbot details result = await robot_virtual( operation="read", robot_id="vbot_scout_01" ) # Update vbot result = await robot_virtual( operation="update", robot_id="vbot_scout_01", scale=1.5, position={"x": 2.0, "y": 0.0, "z": 2.0} ) # Load environment result = await robot_virtual( operation="load_environment", environment="stroheckgasse_apartment", platform="unity" ) # Get LiDAR scan result = await robot_virtual( operation="get_lidar", robot_id="vbot_scout_01" ) # List all vbots result = await robot_virtual(operation="list")

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
operationYes
robot_typeNo
robot_idNo
platformNounity
positionNo
scaleNo
metadataNo
model_pathNo
environmentNo
environment_pathNo
project_pathNo
include_collidersNo

Implementation Reference

  • The main handler function 'robot_virtual' decorated with @mcp.tool(). It defines the input schema and dispatches to specific operation handlers (CRUD and virtual robot ops) based on the 'operation' parameter.
    @self.mcp.tool() async def robot_virtual( operation: Literal[ # CRUD operations "create", "read", "update", "delete", "list", # Virtual robot operations "spawn", "load_environment", "get_status", "get_lidar", "set_scale", "test_navigation", "sync_with_physical", ], robot_type: Optional[str] = None, robot_id: Optional[str] = None, platform: Literal["unity", "vrchat"] = "unity", position: Optional[Dict[str, float]] = None, scale: Optional[float] = None, metadata: Optional[Dict[str, Any]] = None, model_path: Optional[str] = None, environment: Optional[str] = None, environment_path: Optional[str] = None, project_path: Optional[str] = None, include_colliders: bool = True, ) -> Dict[str, Any]: """Virtual robot lifecycle and operations portmanteau. PORTMANTEAU PATTERN: Consolidates virtual robot CRUD operations and virtual robotics operations into a single unified tool. This reduces tool explosion while maintaining full functionality for virtual robot management. CRUD OPERATIONS: - create: Create/spawn and register a new virtual robot - read: Get details of an existing virtual robot - update: Modify virtual robot properties (scale, position, metadata, etc.) - delete: Remove and unregister a virtual robot - list: List all virtual robots with optional filtering VIRTUAL ROBOT OPERATIONS: - spawn: Spawn robot in Unity/VRChat scene (alias for create) - load_environment: Load Marble/Chisel environment into scene - get_status: Get virtual robot status - get_lidar: Get virtual LiDAR scan (Unity physics raycast) - set_scale: Scale robot size (for size testing) - test_navigation: Test pathfinding in environment - sync_with_physical: Sync vbot state with physical bot Args: operation: Operation to perform (see CRUD and Virtual Robot Operations above). robot_type: Type of robot (required for create/spawn). Examples: "scout", "go2", "g1", "robbie", "custom" robot_id: Virtual robot identifier (required for read, update, delete, get_status, etc.). Auto-generated for create/spawn if not provided. platform: Target platform ("unity" or "vrchat"). Default: "unity". position: Spawn/update position (x, y, z) for create/spawn/update. scale: Size multiplier for create/spawn/update/set_scale. metadata: Additional metadata dictionary for create/update. model_path: Path to 3D model file (.glb, .fbx, .vrm) for custom robot_type. environment: Environment name (Marble-generated) for load_environment. environment_path: Path to environment file for load_environment. project_path: Unity project path (optional, auto-detected if not provided). include_colliders: Whether to import collider meshes (default: True). Returns: Dictionary containing operation result with robot details. Examples: # Create a Scout vbot result = await robot_virtual( operation="create", robot_type="scout", platform="unity", position={"x": 0.0, "y": 0.0, "z": 0.0}, scale=1.0 ) # Spawn robot (alias for create) result = await robot_virtual( operation="spawn", robot_type="scout", platform="unity" ) # Read vbot details result = await robot_virtual( operation="read", robot_id="vbot_scout_01" ) # Update vbot result = await robot_virtual( operation="update", robot_id="vbot_scout_01", scale=1.5, position={"x": 2.0, "y": 0.0, "z": 2.0} ) # Load environment result = await robot_virtual( operation="load_environment", environment="stroheckgasse_apartment", platform="unity" ) # Get LiDAR scan result = await robot_virtual( operation="get_lidar", robot_id="vbot_scout_01" ) # List all vbots result = await robot_virtual(operation="list") """ try: # Route to appropriate handler if operation in ["create", "spawn"]: return await self._handle_create(robot_type, robot_id, platform, position, scale, metadata, model_path) elif operation == "read": return await self._handle_read(robot_id) elif operation == "update": return await self._handle_update(robot_id, position, scale, metadata) elif operation == "delete": return await self._handle_delete(robot_id) elif operation == "list": return await self._handle_list(robot_type, platform) elif operation == "load_environment": return await self._handle_load_environment(environment, platform, environment_path, project_path, include_colliders) elif operation == "get_status": return await self._handle_get_status(robot_id) elif operation == "get_lidar": return await self._handle_get_lidar(robot_id) elif operation == "set_scale": return await self._handle_set_scale(robot_id, scale) elif operation == "test_navigation": return await self._handle_test_navigation(robot_id, environment) elif operation == "sync_with_physical": return await self._handle_sync_with_physical(robot_id) else: return format_error_response(f"Unknown operation: {operation}", error_type="validation_error") except Exception as e: return handle_tool_error("robot_virtual", e, operation=operation, robot_type=robot_type, robot_id=robot_id)
  • Input schema for the robot_virtual tool, defining supported operations, robot parameters, and platform-specific args.
    async def robot_virtual( operation: Literal[ # CRUD operations "create", "read", "update", "delete", "list", # Virtual robot operations "spawn", "load_environment", "get_status", "get_lidar", "set_scale", "test_navigation", "sync_with_physical", ], robot_type: Optional[str] = None, robot_id: Optional[str] = None, platform: Literal["unity", "vrchat"] = "unity", position: Optional[Dict[str, float]] = None, scale: Optional[float] = None, metadata: Optional[Dict[str, Any]] = None, model_path: Optional[str] = None, environment: Optional[str] = None, environment_path: Optional[str] = None, project_path: Optional[str] = None, include_colliders: bool = True, ) -> Dict[str, Any]:
  • Registration of the robot_virtual tool by instantiating RobotVirtualTool and calling its register() method in the main server.
    self.robot_virtual.register() # Virtual: CRUD + virtual robot operations logger.debug("Registered robot_virtual tool")
  • Constant defining supported virtual robot types used in validation.
    SUPPORTED_ROBOT_TYPES = ["scout", "scout_e", "go2", "g1", "robbie", "custom"]
  • Example helper handler for 'create'/'spawn' operations, handling validation, registration, spawning in platform (Unity/VRChat), and response formatting.
    async def _handle_create( self, robot_type: Optional[str], robot_id: Optional[str], platform: str, position: Optional[Dict[str, float]], scale: Optional[float], metadata: Optional[Dict[str, Any]], model_path: Optional[str], ) -> Dict[str, Any]: """Create/spawn a new virtual robot.""" if not robot_type: return format_error_response("robot_type is required for create/spawn operation", error_type="validation_error") if robot_type not in SUPPORTED_ROBOT_TYPES: return format_error_response( f"Unsupported robot_type: {robot_type}. Supported: {', '.join(SUPPORTED_ROBOT_TYPES)}", error_type="validation_error", ) if robot_type == "custom" and not model_path: return format_error_response("model_path is required for custom robot_type", error_type="validation_error") if not robot_id: robot_id = f"vbot_{robot_type}_{len(self.state_manager.list_robots(is_virtual=True)) + 1:02d}" if self.state_manager.get_robot(robot_id): return format_error_response(f"Robot {robot_id} already exists", error_type="validation_error") position = position or {"x": 0.0, "y": 0.0, "z": 0.0} scale = scale or 1.0 vbot_metadata = { "spawned": True, "platform": platform, "position": position, "scale": scale, "model_path": model_path, **(metadata or {}), } try: robot = self.state_manager.register_robot(robot_id, robot_type, platform=platform, metadata=vbot_metadata) except ValueError as e: return format_error_response(str(e), error_type="validation_error") spawn_result = await self._spawn_in_platform(robot_id, robot_type, platform, position, scale, model_path) if spawn_result.get("status") != "success": self.state_manager.unregister_robot(robot_id) return spawn_result return format_success_response( f"Virtual robot {robot_id} created successfully", data={"robot_id": robot_id, "robot_type": robot_type, "platform": platform, "position": position, "scale": scale}, robot_id=robot_id, )

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/sandraschi/robotics-mcp'

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