Deckhand is a local-first orchestration service for Stream Deck hardware. It pairs with OpenDeck — OpenDeck handles hardware, buttons, and profiles; Deckhand adds agent monitoring, live data widgets, and signal-driven automation.
Prerequisites: Python 3.11+, uv (recommended) or pip.
git clone <this-repo> && cd Deckhand
uv sync # installs all dependencies into .venvpip alternative
pip install -e ".[test]"You can try Deckhand without any hardware — the Core service runs standalone with two mock agents.
1. Start the service:
uv run uvicorn deckhand.main:app --app-dir src --reload2. List the mock agents:
curl http://127.0.0.1:8000/agentsYou should see mock-1 and mock-2, both "status": "idle".
3. Start an agent and watch it work:
# Start mock-1 — it will run for ~0.5s, then wait for input
curl -X POST http://127.0.0.1:8000/agents/mock-1/start
# Check status (should be "awaiting_input" after ~0.5s)
curl http://127.0.0.1:8000/agents
# Provide input — agent finishes and returns to idle
curl -X POST http://127.0.0.1:8000/agents/mock-1/input \
-H "Content-Type: application/json" -d '{"text": "hello"}'4. Try the state store:
# Send a signal that writes state with a 30s TTL
curl -X POST http://127.0.0.1:8000/signals/webhook/camera.motion \
-H "Content-Type: application/json" \
-d '{"key": "camera.front_door.motion", "active": true, "ttl_seconds": 30}'
# Read it back
curl http://127.0.0.1:8000/state/camera.front_door.motion5. Run the tests:
uv run pytest tests/ -v --asyncio-mode=autoAll 39 Core tests should pass.
Once you're comfortable with the API, add hardware via OpenDeck:
1. Install OpenDeck for your platform.
2. Install the Deckhand plugin:
# macOS
cp -r opendeck-plugin/com.deckhand.plugin.sdPlugin \
~/Library/Application\ Support/OpenDeck/Plugins/
# Linux
cp -r opendeck-plugin/com.deckhand.plugin.sdPlugin \
~/.config/OpenDeck/Plugins/3. Install the plugin's Python dependencies (needed once):
pip install aiohttp websockets4. Restart OpenDeck. A "Deckhand" category appears with five actions:
| Action | What it does |
|---|---|
| Agent Status | Monitor + interact with an agent (start/cancel/input) |
| Data Widget | Display a live state value on a button |
| Run Action | Execute any Deckhand action on press |
| Signal Trigger | Fire a Deckhand signal on press |
| Agent Dashboard | Show a summary of all agents on one button |
Drag Agent Status onto a button, pick mock-1 in the Property Inspector, and press it to start the agent.
Copy config.example.toml to config.toml, or use environment variables:
| Setting | Env var | Default |
|---|---|---|
| Listen host | DECKHAND_HOST |
127.0.0.1 |
| Listen port | DECKHAND_PORT |
8000 |
| Plugin modules | DECKHAND_PLUGINS |
deckhand.plugins.builtin |
| State persistence file | DECKHAND_STATE_FILE |
none (in-memory) |
| API key (optional auth) | DECKHAND_API_KEY |
none (disabled) |
| Config file path | DECKHAND_CONFIG_FILE |
none |
The OpenDeck plugin reads DECKHAND_URL (default http://localhost:8000) and DECKHAND_API_KEY from the environment.
- Plugin Guide — Extend Deckhand Core with custom actions and signals
- OpenDeck Plugin — Install and develop the OpenDeck bridge
- API Reference — HTTP API documentation
- Event Schema — Event types and schema reference
- Example Plugin — Complete plugin with actions, signals, and state
[Add your license here]