Local Worker Setup
Run CueAPI handlers on your local machine without a public URL.
Overview
The CueAPI worker is a pull-based daemon that runs on your machine. It polls CueAPI for pending executions, matches them to local handler scripts, and reports outcomes. No public URL required.
Architecture
CueAPI (cloud) Your Machine
┌──────────┐ ┌──────────────────────┐
│ Poller │ │ cueapi-worker │
│ creates │ │ │
│ execution├──poll────►│ GET /claimable │
│ pending │ │ POST /claim │
│ │◄─outcome──│ run handler script │
│ │ │ POST /outcome │
└──────────┘ └──────────────────────┘
Installation
pip install cueapi-workerConfiguration
Create a YAML config file (e.g., cueapi-worker.yaml):
# API key (or set CUEAPI_API_KEY env var, or run `cueapi login`)
# api_key: cue_sk_your_key_here
# Poll interval in seconds (default: 5)
poll_interval: 5
# Max concurrent handlers (default: 4)
max_concurrent: 4
# Handlers — map task names to commands
handlers:
# Simple handler
backup-db: "pg_dump mydb > /backups/$(date +%Y%m%d).sql"
# Full handler with options
generate-report:
cmd: "python3 generate_report.py"
cwd: "/home/user/scripts"
timeout: 120
env:
REPORT_TYPE: "{{ payload.report_type }}"
OUTPUT_DIR: "/reports"Start the worker
cueapi-worker start --config cueapi-worker.yamlThe worker will:
- Register itself via heartbeat
- Start polling for claimable executions
- Match executions to handlers by
payload.task - Run matched handler scripts
- Report outcomes back to CueAPI
Create a worker transport cue
cueapi create \
--name "daily-report" \
--cron "0 9 * * *" \
--transport worker \
--payload '{"task": "generate-report", "report_type": "daily"}'Note
The payload.task value (generate-report) must match a handler name in your worker config.
Handler configuration
Simple form
A string value is treated as the command:
handlers:
my-task: "python3 run.py"Full form
handlers:
my-task:
cmd: "python3 run.py" # Command to execute (required)
cwd: "/path/to/working/dir" # Working directory (optional)
timeout: 300 # Timeout in seconds (default: 300)
env: # Environment variables (optional)
MY_VAR: "value"
PAYLOAD_FIELD: "{{ payload.field }}"Template variables
Use {{ payload.field }} to inject payload values into environment variables:
handlers:
draft-linkedin:
cmd: "python3 linkedin_agent.py"
timeout: 300
env:
INSTRUCTION: "{{ payload.instruction }}"
CONTEXT_REF: "{{ payload.context_ref }}"
AGENT: "{{ payload.agent }}"Nested fields work with dot notation: {{ payload.config.output_dir }}
Missing fields resolve to empty strings.
Built-in environment variables
Every handler receives these environment variables automatically:
| Variable | Description |
|---|---|
CUEAPI_EXECUTION_ID | The execution ID |
CUEAPI_CUE_ID | The cue ID |
CUEAPI_TASK | The payload.task value |
CUEAPI_SCHEDULED_FOR | ISO timestamp of when this was scheduled |
Checking worker status
cueapi-worker statusInstalling as a service
macOS (launchd)
cueapi-worker install-service --config /path/to/cueapi-worker.yamlCreates a launchd plist at ~/Library/LaunchAgents/com.cueapi.worker.plist. Starts automatically on login.
Linux (systemd)
cueapi-worker install-service --config /path/to/cueapi-worker.yamlCreates a systemd user unit. Enable with:
systemctl --user enable cueapi-worker
systemctl --user start cueapi-workerUninstall
cueapi-worker uninstall-serviceGraceful shutdown
The worker handles SIGINT (Ctrl+C) and SIGTERM gracefully:
- Stops accepting new executions
- Waits for active handlers to finish
- Stops the heartbeat thread
- Exits cleanly