Origin CLI
Origin is an open-source platform for controlling robots and hardware devices. The origin CLI provides commands to start the server, connect hardware, install apps, and launch control interfaces.
Installation
npm install -g originrobot
Or run directly with npx:
npx originrobot up
This installs the origin CLI globally. You can then run origin up to start the server.
Quick Start
# Start the server and dashboard origin up # Install a robotics app from GitHub origin install https://github.com/user/my-robot-app # Launch the app on a connected device origin launch my-robot-app -d toy-car
Once the server is running, open http://localhost:5050 to access the dashboard.
Commands
origin up
Start the Origin server and dashboard.
origin up [options]
| Flag | Default | Description |
|---|---|---|
--port <number> | 5050 | Server port (serves API and dashboard) |
--serial <path> | — | Serial port path (repeatable) |
--bluetooth <path> | — | Bluetooth port path (repeatable) |
--tcp <port> | — | TCP listener port for simulators |
--baud <number> | 9600 | Baud rate for serial/bluetooth |
--token <string> | — | Bearer token for API auth |
--no-dashboard | — | Skip starting the dashboard |
--open | — | Auto-open dashboard in browser |
# Start with a serial device origin up --serial /dev/ttyUSB0 # Start with TCP for simulators, no dashboard origin up --tcp 5051 --no-dashboard # Custom port with authentication origin up --port 8080 --token my-secret
origin install
Install a robotics app into Origin.
origin install <source> [--name <override-id>]
Source types: GitHub URL (cloned via git), local path (symlinked), or tarball URL (downloaded and extracted).
The install process validates the origin-app.json manifest, runs any setup commands defined in the manifest, and registers the app.
# Install from GitHub origin install https://github.com/user/robot-teleop # Install from a local directory (symlink) origin install ./my-local-app # Install with a custom ID origin install https://github.com/user/app --name my-custom-id
origin launch
Launch an installed app on a connected device.
origin launch <app-id> --device <device-id> [--mode dev|prod] [--open]
Launch verifies secrets are configured, resolves template variables, starts backend (if configured), waits for health checks, then starts the frontend.
origin launch mujoco-policy-controller -d unitree-go2 --open
Launching mujoco-policy-controller on device unitree-go2 (dev)...
✓ mujoco-policy-controller is running
frontend -> http://localhost:3001
backend -> http://localhost:8000origin devices
List all connected devices, or inspect a specific device.
origin devices [--json] origin devices info <device-id> [--json]
ID TYPE ACTIONS STATE KEYS unitree-go2 quadruped set_position, set_velocity, stand 37 toy-car wheeled moveFwd, moveLeft, moveRight, stop 3
origin secrets
Manage app secrets. Secrets are injected as environment variables at launch time.
origin secrets set <app-id> <key> <value> origin secrets list <app-id>
origin secrets set remote-teleop OPENAI_API_KEY sk-abc123... ✓ Secret OPENAI_API_KEY set for remote-teleop origin secrets list remote-teleop ✓ OPENAI_API_KEY required OpenAI API key for language commands ✗ CUSTOM_MODEL_URL optional URL to a custom model endpoint
origin status
Display full system status: server info, connected devices, and running apps.
origin status [--json]
Also available: origin stop <app-id>, origin uninstall <app-id>, origin discover, origin profiles.
App Manifest
Every Origin app contains an origin-app.json manifest at its root. This file declares the app's identity, device requirements, runtime configuration, and secrets.
{
"name": "My Robot Controller",
"id": "my-controller",
"version": "0.1.0",
"author": "yourname",
"description": "AI-powered robot controller",
"device": {
"type": "quadruped",
"requiredActions": ["set_pos", "reset"],
"requiredState": ["base_pos_z"]
},
"runtime": {
"type": "nextjs",
"port": 3001,
"devCmd": "pnpm dev",
"env": {
"NEXT_PUBLIC_ORIGIN_URL": "{{origin.url}}",
"NEXT_PUBLIC_DEVICE_ID": "{{device.id}}"
}
},
"backend": {
"type": "python",
"entry": "backend/main.py",
"port": 8000,
"healthCheck": "/api/status"
},
"secrets": [{
"key": "OPENROUTER_API_KEY",
"description": "API key for LLM inference",
"required": true
}]
}Device Requirements
The device object declares what hardware capabilities your app needs. Origin checks these against connected devices before allowing launch.
| Field | Type | Description |
|---|---|---|
type | string | wheeled, quadruped, humanoid, arm, or generic |
requiredActions | string[] | Actions the device must support. Launch blocked if missing. |
requiredState | string[] | State keys the device must report. Launch blocked if missing. |
optionalActions | string[] | Actions used if available. Missing ones produce warnings. |
optionalState | string[] | State keys used if available. Missing ones produce warnings. |
Runtime Config
The runtime object configures the frontend process Origin spawns at launch.
| Field | Type | Description |
|---|---|---|
type | string | Runtime type: nextjs, vite, static |
port | number | Port the frontend listens on |
devCmd | string | Dev mode start command (e.g. pnpm dev) |
startCmd | string | Production start command |
setupCmd | string | Dependency install command |
buildCmd | string | Build command for production |
env | object | Environment variables (supports template variables) |
healthCheck | string | HTTP path to poll after startup |
Backend Config
The optional backend object configures a secondary process (e.g. Python FastAPI) spawned before the frontend.
| Field | Type | Description |
|---|---|---|
type | string | python (uses python3) or node |
entry | string | Entry point file (e.g. backend/main.py) |
port | number | Port the backend listens on |
args | string[] | CLI arguments (supports template variables) |
installCmd | string | Dependency install command |
healthCheck | string | HTTP path Origin polls before starting frontend |
Secrets
Declare API keys or credentials your app needs. Users configure these via the CLI or dashboard before launching. Secrets are injected as environment variables at runtime.
"secrets": [
{
"key": "OPENROUTER_API_KEY",
"description": "OpenRouter API key for LLM inference",
"required": true
}
]Template Variables
Origin resolves these placeholders at launch time in env, args, and other string fields:
| Variable | Resolved To |
|---|---|
{{origin.url}} | Core server URL (e.g. http://localhost:5050) |
{{device.id}} | Target device ID passed at launch |
{{backend.port}} | Backend port from the manifest |
{{app.port}} | Frontend runtime port |
Origin Marketplace
The Origin Marketplace is a community hub for discovering, installing, and sharing robot control apps. Browse ready-made apps for supported devices, or publish your own for others to use.
Installing Apps from the Marketplace
Each app on the marketplace has a GitHub repository URL. Copy it and install with one command:
# Install from a marketplace app's GitHub URL origin install https://github.com/OriginRobotVerse/mujoco-policy-controller # Or install from the dashboard # Navigate to Apps > Install App and paste the URL
Origin clones the repository, reads the manifest, runs setup commands, and registers the app. You can then configure secrets and launch it against any compatible device.
From the Dashboard
The dashboard's Apps section has an Install App button and a banner linking to the marketplace. Paste a GitHub URL into the source field and click Install. The dashboard shows installation progress and lets you view the app once complete.
Publishing to the Marketplace
Any Origin app with a public GitHub repository can be listed on the marketplace. To prepare your app for publishing:
origin-app.json at the repo rootInclude all required fields: name, id, version, device, and runtime. Add author, description, and icon for the marketplace listing.
Use setup, runtime.setupCmd, runtime.buildCmd, and backend.installCmd so that origin install handles everything automatically.
Add entries to the secrets array with clear descriptions so users know what API keys or credentials they need.
Visit the Origin Marketplace and submit your repository URL. Your app will be reviewed and listed for the community.
Requesting New Apps
Don't see an app for your use case? The marketplace accepts community requests. Visit the marketplace to submit a request describing:
- The device type you're targeting (e.g. Unitree Go2, Arduino)
- What the app should do (e.g. teleoperation, gait training, data logging)
- Any specific requirements (backend inference, specific sensors, etc.)
The community and Origin team review requests and may build apps to fill gaps in the ecosystem.
App Categories
API Reference
The Origin server exposes a REST API on port 5050 (default). All endpoints accept and return JSON. If authentication is enabled, include an Authorization: Bearer <token> header.
Devices
| Method | Path | Description |
|---|---|---|
GET | /devices | List all connected devices |
GET | /devices/:id | Device detail: manifest, state, timestamps |
GET | /devices/:id/state | Current state readings |
POST | /devices/:id/actions | Send an action to a device |
GET | /devices/:id/events | SSE stream for a single device |
curl -X POST http://localhost:5050/devices/toy-car/actions \
-H "Content-Type: application/json" \
-d '{"name": "moveFwd", "params": {"speed": 100}}'Apps
| Method | Path | Description |
|---|---|---|
GET | /api/apps | List installed apps |
POST | /api/apps/install | Install an app |
GET | /api/apps/:id | App detail with compatibility matrix |
POST | /api/apps/:id/launch | Launch an app on a device |
POST | /api/apps/:id/stop | Stop a running app |
GET | /api/apps/:id/logs | Fetch app logs |
POST | /api/apps/:id/secrets | Set secrets for an app |
DELETE | /api/apps/:id | Uninstall an app |
Simulators
| Method | Path | Description |
|---|---|---|
POST | /api/simulators/launch | Launch a simulator |
POST | /api/simulators/:id/stop | Stop a running simulator |
GET | /api/simulators | List available models and running sims |
GET | /api/simulators/:id/logs | Fetch simulator logs |
SSE Events
Subscribe to real-time events via /events (global) or /devices/:id/events (per-device).
| Event | Description |
|---|---|
state.updated | Device state readings changed |
action.sent | An action was dispatched to a device |
device.connected | A device announced itself |
device.disconnected | A device transport closed |
const es = new EventSource("http://localhost:5050/devices/toy-car/events");
es.addEventListener("state.updated", (e) => {
const data = JSON.parse(e.data);
console.log("State:", data.data);
});