Skip to main content
Glama
sandraschi

Robotics MCP Server

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

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault

No arguments

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,
        )
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries full burden and does well by detailing what each operation does (e.g., 'spawn robot in Unity/VRChat scene', 'Get virtual LiDAR scan (Unity physics raycast)', 'Sync vbot state with physical bot'). It explains behavioral aspects like auto-generation of robot_id, default values, and specific implementation details. No contradictions exist since annotations are absent.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is well-structured with clear sections (PORTMANTEAU PATTERN, CRUD OPERATIONS, VIRTUAL ROBOT OPERATIONS, Args, Returns, Examples) and front-loaded purpose. However, it's quite lengthy due to comprehensive parameter documentation, which is necessary given the complexity but slightly reduces conciseness.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the high complexity (12 parameters, multiple operations), no annotations, and an output schema present, the description is highly complete. It covers purpose, operations, detailed parameter semantics, return format, and examples, providing all necessary context for an agent to use the tool effectively without relying on structured fields.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate fully. It provides detailed parameter explanations in the 'Args' section, including purpose, requirements, examples, and defaults for all 12 parameters. This adds substantial meaning beyond the bare schema, making parameter usage clear.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description explicitly states this is a 'portmanteau' tool that 'consolidates virtual robot CRUD operations and virtual robotics operations into a single unified tool.' It clearly distinguishes from siblings by specifying it handles virtual robot lifecycle and operations, unlike tools like robot_behavior or robot_control which likely handle different aspects.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage through the portmanteau pattern explanation and operation lists, but doesn't explicitly state when to use this tool versus alternatives like vbot_crud or robotics_system. It provides functional grouping but lacks explicit guidance on tool selection among siblings.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

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