Metadata-Version: 2.4
Name: opencastor
Version: 2026.3.20.4
Summary: The Universal Runtime for Embodied AI
Author-email: OpenCastor Contributors <hello@opencastor.com>
License-Expression: Apache-2.0
Project-URL: Homepage, https://opencastor.com
Project-URL: Repository, https://github.com/craigm26/OpenCastor
Project-URL: Documentation, https://opencastor.com/docs
Project-URL: Bug Tracker, https://github.com/craigm26/OpenCastor/issues
Project-URL: Changelog, https://github.com/craigm26/OpenCastor/blob/main/CHANGELOG.md
Project-URL: Discord, https://discord.gg/jMjA8B26Bq
Keywords: robotics,ai,llm,embodied-ai,rcan
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Science/Research
Classifier: Operating System :: OS Independent
Classifier: Operating System :: POSIX :: Linux
Classifier: Operating System :: MacOS
Classifier: Operating System :: Microsoft :: Windows
Classifier: Environment :: Console
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Classifier: Topic :: System :: Hardware
Requires-Python: <3.14,>=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: anthropic>=0.40.0
Requires-Dist: openai>=1.0.0
Requires-Dist: pyserial>=3.5
Requires-Dist: opencv-python-headless>=4.9.0
Requires-Dist: gTTS>=2.4.0
Requires-Dist: pygame>=2.5.0
Requires-Dist: pyyaml>=6.0
Requires-Dist: jsonschema>=4.20.0
Requires-Dist: requests>=2.31.0
Requires-Dist: fastapi>=0.109.0
Requires-Dist: uvicorn[standard]>=0.27.0
Requires-Dist: python-dotenv>=1.0.0
Requires-Dist: httpx>=0.26.0
Requires-Dist: python-multipart>=0.0.7
Requires-Dist: huggingface-hub>=0.25.0
Requires-Dist: streamlit>=1.30.0
Requires-Dist: SpeechRecognition>=3.10.0
Requires-Dist: PyJWT>=2.8.0
Requires-Dist: rich>=13.0.0
Requires-Dist: argcomplete>=3.0.0
Requires-Dist: rcan<1.0,>=0.6.0
Provides-Extra: core
Provides-Extra: rpi
Requires-Dist: adafruit-circuitpython-pca9685>=3.4.0; sys_platform == "linux" and extra == "rpi"
Requires-Dist: adafruit-circuitpython-motor>=3.4.0; sys_platform == "linux" and extra == "rpi"
Requires-Dist: neonize==0.3.15.post0; extra == "rpi"
Requires-Dist: picamera2>=0.3; sys_platform == "linux" and extra == "rpi"
Provides-Extra: elevenlabs
Requires-Dist: elevenlabs>=1.0; extra == "elevenlabs"
Provides-Extra: sdk
Requires-Dist: httpx>=0.27; extra == "sdk"
Provides-Extra: whatsapp
Requires-Dist: neonize==0.3.15.post0; extra == "whatsapp"
Provides-Extra: whatsapp-twilio
Requires-Dist: twilio>=9.0.0; extra == "whatsapp-twilio"
Provides-Extra: telegram
Requires-Dist: python-telegram-bot>=21.0; extra == "telegram"
Provides-Extra: discord
Requires-Dist: discord.py>=2.3.0; extra == "discord"
Provides-Extra: slack
Requires-Dist: slack-bolt>=1.18.0; extra == "slack"
Provides-Extra: mqtt
Requires-Dist: paho-mqtt>=2.0.0; extra == "mqtt"
Provides-Extra: channels
Requires-Dist: neonize==0.3.15.post0; extra == "channels"
Requires-Dist: python-telegram-bot>=21.0; extra == "channels"
Requires-Dist: discord.py>=2.3.0; extra == "channels"
Requires-Dist: slack-bolt>=1.18.0; extra == "channels"
Requires-Dist: paho-mqtt>=2.0.0; extra == "channels"
Provides-Extra: rcan
Requires-Dist: zeroconf>=0.131.0; extra == "rcan"
Requires-Dist: rcan<1.0,>=0.6.0; extra == "rcan"
Provides-Extra: dynamixel
Requires-Dist: dynamixel-sdk>=3.7.31; extra == "dynamixel"
Provides-Extra: hlabs
Requires-Dist: python-can>=4.0; extra == "hlabs"
Provides-Extra: lerobot
Requires-Dist: feetech-servo-sdk; extra == "lerobot"
Requires-Dist: dynamixel-sdk>=3.8; extra == "lerobot"
Requires-Dist: gym-pusht; extra == "lerobot"
Requires-Dist: gym-aloha; extra == "lerobot"
Provides-Extra: reachy
Requires-Dist: reachy2-sdk>=1.0; extra == "reachy"
Requires-Dist: zeroconf>=0.120; extra == "reachy"
Provides-Extra: cloud
Requires-Dist: firebase-admin>=6.0.0; extra == "cloud"
Requires-Dist: httpx>=0.27; extra == "cloud"
Provides-Extra: setup
Requires-Dist: qrcode[pil]>=7.0; extra == "setup"
Provides-Extra: esp32
Requires-Dist: websocket-client>=1.7.0; extra == "esp32"
Provides-Extra: ev3
Requires-Dist: python-ev3dev2>=2.1.0.post1; sys_platform == "linux" and extra == "ev3"
Provides-Extra: spike
Requires-Dist: bleak>=0.22.0; extra == "spike"
Provides-Extra: stem-hardware
Requires-Dist: websocket-client>=1.7.0; extra == "stem-hardware"
Requires-Dist: python-ev3dev2>=2.1.0.post1; sys_platform == "linux" and extra == "stem-hardware"
Requires-Dist: bleak>=0.22.0; extra == "stem-hardware"
Provides-Extra: vertex
Requires-Dist: google-genai>=1.0.0; extra == "vertex"
Provides-Extra: homeassistant
Requires-Dist: aiohttp>=3.9.0; extra == "homeassistant"
Provides-Extra: webrtc
Requires-Dist: aiortc>=1.6.0; extra == "webrtc"
Requires-Dist: av>=11.0.0; extra == "webrtc"
Provides-Extra: ros2
Provides-Extra: onnx
Requires-Dist: onnxruntime>=1.17.0; extra == "onnx"
Provides-Extra: onnx-gpu
Requires-Dist: onnxruntime-gpu>=1.17.0; extra == "onnx-gpu"
Provides-Extra: gestures
Requires-Dist: mediapipe>=0.10.0; extra == "gestures"
Provides-Extra: apple
Provides-Extra: simulation
Provides-Extra: all
Requires-Dist: python-telegram-bot>=21.0; extra == "all"
Requires-Dist: discord.py>=2.3.0; extra == "all"
Requires-Dist: slack-bolt>=1.18.0; extra == "all"
Requires-Dist: paho-mqtt>=2.0.0; extra == "all"
Requires-Dist: zeroconf>=0.131.0; extra == "all"
Requires-Dist: dynamixel-sdk>=3.7.31; extra == "all"
Requires-Dist: google-genai>=1.0.0; extra == "all"
Requires-Dist: aiohttp>=3.9.0; extra == "all"
Requires-Dist: aiortc>=1.6.0; extra == "all"
Requires-Dist: av>=11.0.0; extra == "all"
Requires-Dist: onnxruntime>=1.17.0; extra == "all"
Requires-Dist: mediapipe>=0.10.0; extra == "all"
Requires-Dist: pytest>=8.0.0; extra == "all"
Requires-Dist: pytest-asyncio>=0.23.0; extra == "all"
Requires-Dist: pytest-cov>=4.1.0; extra == "all"
Requires-Dist: ruff>=0.2.0; extra == "all"
Requires-Dist: qrcode>=7.4.0; extra == "all"
Provides-Extra: dev
Requires-Dist: pytest>=8.0.0; extra == "dev"
Requires-Dist: pytest-asyncio>=0.23.0; extra == "dev"
Requires-Dist: pytest-cov>=4.1.0; extra == "dev"
Requires-Dist: ruff>=0.2.0; extra == "dev"
Requires-Dist: qrcode>=7.4.0; extra == "dev"
Requires-Dist: cyclonedx-bom>=4.0; extra == "dev"
Dynamic: license-file

<p align="center">
  <img src="brand/icon-192.png" alt="OpenCastor" width="200"/>
</p>

<h1 align="center">OpenCastor</h1>

<p align="center">
  Open-source robot runtime — connect any AI model to any robot hardware through a single YAML config.
</p>

<p align="center">
  <a href="https://pypi.org/project/opencastor/"><img src="https://img.shields.io/pypi/v/opencastor?color=blue&label=PyPI" alt="PyPI"></a>
  <a href="https://rcan.dev/spec/"><img src="https://img.shields.io/badge/RCAN-v1.6-brightgreen" alt="RCAN v1.6"></a>
  <a href="https://rcan.dev/docs/safety/"><img src="https://img.shields.io/badge/Protocol%2066-94%25-orange" alt="Protocol 66"></a>
  <a href="https://github.com/craigm26/OpenCastor/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-Apache%202.0-green" alt="License"></a>
  <a href="https://github.com/craigm26/OpenCastor/actions"><img src="https://img.shields.io/github/actions/workflow/status/craigm26/OpenCastor/ci.yml?label=CI" alt="CI"></a>
  <a href="https://app.opencastor.com"><img src="https://img.shields.io/badge/Fleet%20UI-app.opencastor.com-orange" alt="Fleet UI"></a>
  <a href="https://discord.gg/jMjA8B26Bq"><img src="https://img.shields.io/badge/Discord-join-5865F2?logo=discord&logoColor=white" alt="Discord"></a>
</p>

<p align="center">
  <b>94,438 lines of Python · 7,334 tests · Python 3.10–3.13</b>
</p>

---

## What is OpenCastor

OpenCastor is an open-source runtime for embodied AI. It implements the [RCAN open protocol](https://rcan.dev/spec/) and handles the hard parts: safety gates, multi-provider AI routing, hardware drivers, messaging channels, and fleet management.

Point it at any LLM (Gemini, GPT-4.1, Claude, Ollama, and 13 more) and any robot body (Raspberry Pi, Jetson, Arduino, ESP32, LEGO) via a single YAML config. Your robot answers to WhatsApp, Telegram, Discord, Slack, and Home Assistant — and learns from its own experience through the Sisyphus self-improvement loop.

> **RCAN ≠ OpenCastor.** [RCAN](https://rcan.dev) is an independent open protocol — like DNS and ICANN, but for robotics. Any robot can implement RCAN without using OpenCastor. OpenCastor is one implementation that helped inform the spec.

## Quick Start

### 1. Install

```bash
pip install opencastor==2026.4.1.0
```

### 2. Run the setup wizard

```bash
castor setup
```

The wizard will:
- Name your robot and assign an RRN (Robot Registration Number)
- Generate a config file at `~/.config/opencastor/<name>.rcan.yaml`
- Show a QR code to connect to the Fleet UI at [app.opencastor.com](https://app.opencastor.com)
- Configure your AI brain provider (Gemini, Claude, OpenAI, or local Ollama)

### 3. Start your robot

```bash
# Start the AI brain + REST API (port 8000)
castor gateway --config ~/.config/opencastor/bob.rcan.yaml

# Start the cloud bridge (connects robot to Fleet UI — outbound-only)
castor bridge --config ~/.config/opencastor/bob.rcan.yaml
```

### 4. One-command systemd setup

```bash
castor bridge setup   # generates and optionally installs systemd services
```

### Docker

```bash
docker run -it \
  -v ~/.config/opencastor:/config \
  -e OPENCASTOR_CONFIG=/config/bob.rcan.yaml \
  ghcr.io/craigm26/opencastor:2026.4.1.0 \
  castor gateway
```


<!-- SETUP_CATALOG:BEGIN -->
| Profile | Description | Requires |
|---|---|---|
| `apple_native` | Mac with Apple Silicon (M1–M4) — runs models on-device via Apple Foundation Models. No API key needed. | macOS, Apple Silicon |
| `mlx_local_vision` | Mac with Apple Silicon — open-source models via MLX (Llama, Mistral, Qwen). More model choice than apple_native. | macOS, Apple Silicon |
| `ollama_universal_local` | Any machine — runs local models via Ollama. Works on Mac, Linux, and Windows. | [Ollama](https://ollama.com) installed |

**On Apple Silicon, `apple_native` is the default.** The wizard will ask which Apple model profile fits your use case:

| Apple Profile | Use case | Guardrails |
|---|---|---|
| `apple-balanced` ⭐ | General chat and robot commands — best starting point | Default |
| `apple-creative` | Creative tasks, less restrictive output | Permissive Content Transformations |
| `apple-tagging` | Classifying or labeling objects/scenes | Default |
<!-- SETUP_CATALOG:END -->

## Features

- **Protocol 66 safety** — ESTOP never blocked, local safety always wins, confidence gates run on-device
- **RCAN v1.6** — replay prevention, federation, constrained transport (BLE/LoRa), multi-modal payloads, Level of Assurance
- **Multi-provider AI** — Gemini, Claude, OpenAI, Ollama, MLX (Apple Silicon), Groq, DeepSeek, and 7 more; hot-swap via YAML
- **Fleet UI** — real-time fleet dashboard at [app.opencastor.com](https://app.opencastor.com); no port forwarding needed
- **SO-ARM101 arm support** — auto-detected via USB, guided setup for follower/leader/bimanual configurations
- **18 hardware presets** — Raspberry Pi, Jetson, Arduino, ESP32, LEGO Mindstorms, OAK-D, LeRobot SO-ARM101, and more
- **Self-improving loop** — Sisyphus PM→Dev→QA→Apply pipeline learns from every episode
- **Messaging channels** — WhatsApp, Telegram, Discord, Slack, Home Assistant, MQTT
- **castor setup wizard** — guided onboarding with QR codes; works headless on Pi

## Architecture

```
[ app.opencastor.com / Fleet UI ]
          │  Firebase / Firestore
          │
   [ Cloud Functions ]            R2RAM enforcement + rate limiting
          │
   [ castor bridge ]              outbound-only Firestore connection
          │
   [ castor gateway ]             FastAPI REST + messaging channels
          │
   ┌──────────────────────┐
   │   Protocol 66 Safety │       ESTOP | confidence gates | bounds
   └──────────────────────┘
          │
   [ Tiered Brain ]               Gemini / Claude / GPT / Ollama / …
          │
   [ RCAN Config + Drivers ]      .rcan.yaml → hardware abstraction
          │
   [ Robot Hardware ]             Pi / Jetson / Arduino / SO-ARM101 / …
```

## RCAN v1.6 Features

| Feature | Description |
|---|---|
| Replay prevention | Sliding-window `msg_id` cache; stale messages rejected |
| Federation | Cross-registry consent, DNS trust anchors, JWT verification |
| Constrained transport | Compact CBOR (512B), 32-byte ESTOP minimal for BLE/LoRa |
| Multi-modal payloads | Inline or referenced media chunks; streaming sensor data |
| Level of Assurance | LoA 1/2/3 on operator JWTs; configurable minimum per scope |

## castor CLI Reference

| Command | Description |
|---|---|
| `castor setup` | Interactive onboarding wizard — config, RRN, Fleet UI QR code |
| `castor gateway` | Start AI brain + REST API + messaging channels |
| `castor bridge` | Start cloud bridge (Fleet UI connection) |
| `castor scan` | Auto-detect connected hardware (USB, I2C, V4L2) |
| `castor doctor` | System health check — providers, channels, hardware |
| `castor fix` | Auto-fix common configuration issues |
| `castor status` | Provider and channel readiness summary |
| `castor improve` | Run Sisyphus self-improvement on recent episodes |
| `castor audit --verify` | Verify audit chain integrity |
| `castor approvals` | Review and approve pending high-risk commands |
| `castor deploy` | Push config to a remote robot over SSH |
| `castor fleet` | Discover and monitor all robots on the local network |
| `castor upgrade` | Pull latest version + pip install + service restart |

Full reference: [`docs/claude/cli-reference.md`](docs/claude/cli-reference.md)

## Configuration

Minimal `bob.rcan.yaml`:

```yaml
rcan_version: "1.6"
metadata:
  robot_name: bob
agent:
  provider: google
  model: gemini-2.5-flash
drivers:
  - id: wheels
    protocol: pca9685
channels: {}
```

That's it. `castor gateway --config bob.rcan.yaml` starts the REST API, messaging channels, and the self-improving loop.

Swap the AI brain with one line:

```yaml
agent:
  provider: anthropic
  model: claude-sonnet-4-6
```

## Protocol 66

Protocol 66 is RCAN's mandatory safety layer. Current OpenCastor conformance: **94%**.

Key invariants:
- ESTOP delivered at QoS 2 (EXACTLY_ONCE) — never blocked by backpressure
- Local safety always wins — cloud commands pass through the same confidence gates as local commands
- Audit chain required for all flagged commands
- `GuardianAgent` has veto authority over unsafe actions

P66 manifest: [`sbom/`](sbom/) · Full spec: [rcan.dev/docs/safety/](https://rcan.dev/docs/safety/)

## Fleet UI

**[app.opencastor.com](https://app.opencastor.com)** — sign in with Google to see your fleet.

- Real-time status cards for all registered robots
- Robot detail: telemetry, command history, chat-scope instructions
- ESTOP button on every screen
- Consent management — approve/deny R2RAM access requests
- Revocation display — shows if a robot's identity has been revoked
- LoA display — shows operator Level of Assurance on control commands

Robots connect via `castor bridge` (outbound-only Firestore). No open ports on the robot side.

## SO-ARM101 Arm Support

The LeRobot SO-ARM101 6-DOF serial bus servo arm is auto-detected via USB VID/PID (CH340, `0x1A86/0x7523`).

```bash
pip install opencastor[lerobot]
castor scan                          # detects arm + suggests preset
castor wizard --preset so_arm101     # guided config: follower / leader / bimanual
castor gateway --config so_arm101.rcan.yaml
```

`castor scan` counts connected Feetech boards and automatically suggests the right preset: single arm (follower or leader), or bimanual pair (ALOHA-style). Koch arms use the same detection path.

## Ecosystem

| Project | Version | Purpose |
|---|---|---|
| **OpenCastor** (this) | v2026.3.17.13 | Robot runtime, RCAN reference implementation |
| [Fleet UI](https://app.opencastor.com) | live | Web fleet dashboard |
| [RCAN Protocol](https://rcan.dev/spec/) | v1.6.0 | Open robot communication standard |
| [rcan-py](https://github.com/continuonai/rcan-py) | v0.6.0 | Python RCAN SDK |
| [rcan-ts](https://github.com/continuonai/rcan-ts) | v0.6.0 | TypeScript RCAN SDK |
| [Robot Registry Foundation](https://robotregistryfoundation.org) | v1.6.0 | Global robot identity registry |

## Contributing

OpenCastor is Apache 2.0 and community-driven.

- **Discord**: [discord.gg/jMjA8B26Bq](https://discord.gg/jMjA8B26Bq)
- **Issues**: [github.com/craigm26/OpenCastor/issues](https://github.com/craigm26/OpenCastor/issues)
- **PRs**: See [CONTRIBUTING.md](CONTRIBUTING.md)
- **Docs**: [`docs/claude/`](docs/claude/) — structure, API reference, env vars

## License

Apache 2.0 · by [Craig Merry](https://github.com/craigm26)

Implements the [RCAN open protocol](https://rcan.dev/spec/). RCAN is an independent open standard — any robot or runtime can implement it.
