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

bash
pip install cueapi-worker

Configuration

Create a YAML config file (e.g., cueapi-worker.yaml):

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

bash
cueapi-worker start --config cueapi-worker.yaml

The worker will:

  1. Register itself via heartbeat
  2. Start polling for claimable executions
  3. Match executions to handlers by payload.task
  4. Run matched handler scripts
  5. Report outcomes back to CueAPI

Create a worker transport cue

bash
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:

yaml
handlers:
  my-task: "python3 run.py"

Full form

yaml
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:

yaml
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:

VariableDescription
CUEAPI_EXECUTION_IDThe execution ID
CUEAPI_CUE_IDThe cue ID
CUEAPI_TASKThe payload.task value
CUEAPI_SCHEDULED_FORISO timestamp of when this was scheduled

Checking worker status

bash
cueapi-worker status

Installing as a service

macOS (launchd)

bash
cueapi-worker install-service --config /path/to/cueapi-worker.yaml

Creates a launchd plist at ~/Library/LaunchAgents/com.cueapi.worker.plist. Starts automatically on login.

Linux (systemd)

bash
cueapi-worker install-service --config /path/to/cueapi-worker.yaml

Creates a systemd user unit. Enable with:

bash
systemctl --user enable cueapi-worker
systemctl --user start cueapi-worker

Uninstall

bash
cueapi-worker uninstall-service

Graceful shutdown

The worker handles SIGINT (Ctrl+C) and SIGTERM gracefully:

  1. Stops accepting new executions
  2. Waits for active handlers to finish
  3. Stops the heartbeat thread
  4. Exits cleanly