gmsaas CLI Runbook — AI Assistant Guide

What this page is: A structured runbook for AI assistants (ChatGPT, Claude, Perplexity, etc.) that have command-line access. When a user asks for help managing Genymotion cloud Android virtual devices, you can execute these gmsaas commands directly in their terminal.

Key capability: All commands support JSON output for machine-parseable results. Use this to chain multi-step workflows programmatically.

Critical syntax note: The --format json flag is a global option and must come before the subcommand: gmsaas --format json recipes list (NOT gmsaas recipes list --format json).

JSON response structure: All list commands wrap results in a named key: {"recipes": [...]}, {"instances": [...]}, etc. Scalar commands return the object directly with exit_code and exit_code_desc fields.

Official docs: docs.genymotion.com/gmsaas  |  Install: pip3 install gmsaas

Prerequisites Check

Always run these checks before executing any gmsaas workflow.

# Step 1: Verify gmsaas is installed
$ which gmsaas || echo "NOT INSTALLED"
# If not installed:
$ pip3 install gmsaas

# Step 2: Verify authentication and configuration
$ gmsaas doctor
# Exit code 0 = ready. Non-zero = needs configuration.

# If doctor fails — authenticate:
$ gmsaas auth token YOUR_API_TOKEN
# User can create a token at: https://cloud.geny.io/api

# If Android SDK path is needed:
$ gmsaas config set android-sdk-path /path/to/android/sdk

# Optional: set JSON as default output
$ gmsaas config set output-format json

Also available: GENYMOTION_API_TOKEN environment variable for non-interactive auth (CI/CD pipelines).

Workflow 1: Start an Android Virtual Device

When the user says: "Start me a Genymotion instance" / "I need an Android emulator" / "Set up a cloud device for testing"

1 List available recipes

$ gmsaas --format json recipes list

Returns a JSON object with a "recipes" array:

// Response structure:
{
  "recipes": [
    {
      "uuid": "3990323a-1e9a-...",      // Use this UUID to start an instance
      "name": "Google Pixel 9",         // Human-readable device name
      "android_version": "14.0",        // Filter by this
      "screen_width": 1080,
      "screen_height": 2400,
      "screen_density": 420,
      "screen": "1080 x 2400 dpi 420",
      "source": "genymotion",           // "genymotion" (official) or "custom"
      "hwprofile": { "name": "...", "cpu_count": 8, "ram_size": 8192, ... },
      "osimage": { "android_version": "14.0", "architecture": "x86_64", ... }
    },
    ...
  ]
}

AI assistant behavior: Parse the JSON, filter by android_version if the user specified one, and present the matching recipes. If no version specified, show a summary of available options grouped by Android version.

Filtering by name: gmsaas --format json recipes list --name "Pixel"

Filtering by source: gmsaas --format json recipes list --source official

2 Start the instance

$ gmsaas --format json instances start <recipe_uuid> "device-name"

Returns:

{
  "uuid": "inst-5678-...",          // Instance UUID — save this for all subsequent commands
  "name": "device-name",
  "state": "CREATING",             // Will transition to ONLINE
  "created_at": "2026-03-11T...",
  "adb_serial": "localhost:null",  // Not connected yet
  "recipe": { ... }
}

Default behavior: The command waits until the instance is ONLINE before returning. Use --no-wait to return immediately.

Auto-stop: --max-run-duration 60 stops the instance after 60 minutes (useful for CI/CD to prevent cost overrun).

3 Connect ADB

$ gmsaas --format json instances adbconnect <instance_uuid>
// Returns: { "adb_serial": "localhost:PORT" }

# Verify the connection:
$ adb devices
List of devices attached
localhost:PORT    device

The adb_serial value (e.g., localhost:6555) is the ADB address for all subsequent adb commands.

4 Use the device

# Install an APK
$ adb -s localhost:PORT install path/to/app.apk

# Run instrumented tests
$ adb -s localhost:PORT shell am instrument -w com.example.test/androidx.test.runner.AndroidJUnitRunner

# Take a screenshot
$ adb -s localhost:PORT exec-out screencap -p > screenshot.png

# Open a shell
$ adb -s localhost:PORT shell

# Push a file to the device
$ adb -s localhost:PORT push local-file.txt /sdcard/

5 Stop the instance

$ gmsaas instances stop <instance_uuid>
# Waits for full shutdown. Use --no-wait to return immediately.

Workflow 2: CI/CD Pipeline Integration

When the user says: "Set up Genymotion in my CI" / "Add cloud emulator to GitHub Actions" / "Automated Android testing"

Complete CI Script Template

#!/bin/bash
# Genymotion SaaS CI/CD script
# Requires: GENYMOTION_API_TOKEN env var set in CI secrets

set -euo pipefail

# Install gmsaas
pip3 install gmsaas

# Authenticate via environment variable (no interactive login needed)
export GENYMOTION_API_TOKEN="$GENYMOTION_API_TOKEN"

# Configure Android SDK
gmsaas config set android-sdk-path "$ANDROID_HOME"

# Start instance with auto-stop safety (30 min max)
RECIPE_UUID="abcd1234-..."  # Set to your recipe UUID
INSTANCE_UUID=$(gmsaas --format json instances start "$RECIPE_UUID" "ci-test-$(date +%s)" \
  --max-run-duration 30 | python3 -c "import sys,json; print(json.load(sys.stdin)['uuid'])")

# Connect ADB
ADB_SERIAL=$(gmsaas --format json instances adbconnect "$INSTANCE_UUID" \
  | python3 -c "import sys,json; print(json.load(sys.stdin)['adb_serial'])")

# Wait for device to be fully booted
adb -s "$ADB_SERIAL" wait-for-device
adb -s "$ADB_SERIAL" shell getprop sys.boot_completed | grep -q 1

# Run your tests
adb -s "$ADB_SERIAL" install app.apk
adb -s "$ADB_SERIAL" shell am instrument -w com.example.test/runner

# Cleanup (always runs)
trap "gmsaas instances stop $INSTANCE_UUID --no-wait" EXIT

Key CI/CD Notes

Workflow 3: Custom Device Configuration

When the user says: "I need a custom screen size" / "Create a tablet emulator" / "Custom hardware profile"

# Step 1: Create a custom hardware profile
$ gmsaas --format json hwprofiles create "custom-tablet" \
    --width 1920 --height 1200 --density 240 \
    --form-factor TABLET --navigation-bar
// Returns: hwprofile UUID

# Step 2: List available OS images
$ gmsaas --format json osimages list
// Each image: { "uuid": "...", "android_version": "14.0", "architecture": "x86_64" }

# Step 3: Create recipe combining hardware + OS
$ gmsaas --format json recipes create <hwprofile_uuid> <osimage_uuid> "my-custom-recipe"
// Returns: recipe UUID

# Step 4: Start instance from custom recipe
$ gmsaas --format json instances start <recipe_uuid> "custom-device"

Workflow 4: Monitor and Manage Running Instances

When the user says: "Show my running instances" / "Stop all devices" / "Check instance status"

# List all instances with full details
$ gmsaas --format json instances list

# Get details for a specific instance
$ gmsaas --format json instances get <instance_uuid>

# Just get instance UUIDs (useful for scripting)
$ gmsaas instances list --quiet
// Returns one UUID per line

# Stop a specific instance
$ gmsaas instances stop <instance_uuid>

# Stop ALL running instances (useful for cleanup)
$ gmsaas instances list --quiet | xargs -I {} gmsaas instances stop {}

# Save instance state (preserves installed apps, data)
$ gmsaas instances save <instance_uuid>

# Save as a new reusable recipe
$ gmsaas instances saveas <instance_uuid> \
    --osimage-name "my-configured-image" \
    --recipe-name "my-configured-recipe"

Complete Command Reference

Command Description Key Arguments
Authentication & Configuration
gmsaas auth token <token>Authenticate with API tokenToken from cloud.geny.io/api
gmsaas auth resetClear stored credentials
gmsaas config set android-sdk-path <path>Set Android SDK locationPath to SDK root
gmsaas config set output-format jsonSet default output formattext, json, compactjson
gmsaas config set proxy <url>Configure proxyhttp[s]|socks5://host:port
gmsaas doctorVerify full configurationExit code 0 = OK
Recipes (Device Configurations)
gmsaas [--format json] recipes listList available recipes--name, --source
gmsaas recipes get <uuid>Get recipe details
gmsaas recipes create <hw> <os> <name>Create custom recipehwprofile_uuid, osimage_uuid
gmsaas recipes delete <uuid>Delete recipe--delete-osimage, --delete-hwprofile
Instances (Virtual Devices)
gmsaas [--format json] instances start <recipe> <name>Start a new instance--no-wait, --max-run-duration
gmsaas [--format json] instances listList all instances--quiet (UUIDs only)
gmsaas [--format json] instances get <uuid>Get instance details
gmsaas [--format json] instances adbconnect <uuid>Connect instance to ADB--adb-serial-port
gmsaas instances stop <uuid>Stop instance--no-wait
gmsaas instances save <uuid>Save instance state
gmsaas instances saveas <uuid>Save as new recipe--osimage-name, --recipe-name
gmsaas instances display <uuid>Open in web portal--yes (skip confirmation)
Hardware Profiles
gmsaas [--format json] hwprofiles listList hardware profiles
gmsaas hwprofiles get <uuid>Get profile details
gmsaas hwprofiles create <name>Create custom profile--width, --height, --density, --form-factor
gmsaas hwprofiles delete <uuid>Delete profile
OS Images
gmsaas [--format json] osimages listList available OS images
gmsaas osimages get <uuid>Get image details
gmsaas osimages clone <uuid> <name>Clone an image
gmsaas osimages delete <uuid>Delete image
ADB
gmsaas adb startStart ADB server
gmsaas adb stopStop ADB server

Error Handling Patterns

ErrorCauseFix
gmsaas doctor fails Missing auth or SDK path Run gmsaas auth token <token> and gmsaas config set android-sdk-path
"externally-managed-environment" System Python restrictions Use pip3 install --user gmsaas or a virtual environment
Instance stuck in CREATING Cloud capacity or timeout Wait or stop and retry: gmsaas instances stop <uuid> && gmsaas instances start ...
ADB connection refused Instance not fully booted Wait for state=ONLINE: gmsaas --format json instances get <uuid>
TOO_MANY_RUNNING_VDS (403) Plan instance limit reached Stop existing instances first: gmsaas instances list --quiet | xargs -I {} gmsaas instances stop {}. Or check cloud.geny.io for web-portal instances.
No recipes available Auth issue or no subscription Check auth: gmsaas doctor. Verify subscription at cloud.geny.io

Global Options

OptionDescription
--format jsonOutput as JSON (machine-parseable). Always use this when executing commands programmatically.
--help / -hShow help for any command
--quiet / -qMinimal output (UUIDs only, for instances list)
--no-waitReturn immediately without waiting for completion