| name | hue-instant-control |
| description | Instant Philips Hue control via the local Hue Gateway HTTP API. Translates fuzzy requests ("vibes") and natural
language into concrete room/zone/light actions (on/off, brightness, color temperature, simple colors).
Use when the user asks to control Philips Hue lights (or mentions Hue, Hue Bridge, Hue scenes) and you can reach the
Hue Gateway from the execution environment.
|
| license | MIT |
| compatibility | Requires reachability to the Hue Gateway and ability to make HTTP requests. The base URL depends on where commands
execute (host vs sandbox). Requires curl; jq/python3 are optional helpers. Use the server-side `hueGateway` tool when
available; use Bash/curl only as fallback or when explicitly requested.
|
| allowed-tools | Read Bash |
| metadata | {"author":"remcochat","version":"0.4.1","purpose":"hue-gateway-instant-control"} |
Hue Instant Control (Hue Gateway v2)
You control Philips Hue only via the already-running Hue Gateway service.
You translate fuzzy user requests into specific actions on specific Hue entities (rooms/zones/lights).
Keep the interaction short, confident, and “assistant-y”.
Preferred execution path (when available)
If you have access to the server-side tool hueGateway, use it.
- It calls Hue Gateway v2 (
POST /v2/actions) directly from the server (no bash/curl).
- It applies safe defaults and deterministic correlation/idempotency keys.
- Use it for:
inventory.snapshot, room.set, zone.set, light.set, grouped_light.set, scene.activate, resolve.by_name, actions.batch.
clipv2.request is an escape hatch but should be GET/HEAD/OPTIONS only.
Read-only rule (important):
- For “list/what’s in …” requests, do exactly 1
hueGateway call: inventory.snapshot, then answer from the snapshot.
- Avoid chaining
resolve.by_name for simple listing; you can match names directly in result.rooms[] / result.zones[] and filter result.lights[].
Only use Bash/curl when:
- the user explicitly asks for bash/curl,
- tool calling is unavailable, or
- Hue Gateway tooling is disabled by config / access policy.
Performance goal (always)
- Goal: operate the Hue Gateway with near-zero errors and minimal latency.
- Default: 1 tool call per user request (prefer
hueGateway; otherwise 1 Bash tool call bundling all curl calls).
- Do not waste time: avoid repeated health/discovery work once the gateway is known reachable.
- Always use tight timeouts on curl so fallbacks are instant.
Safety + UX rules (always)
- Never guess the target.
- If the room/zone/light is unclear or ambiguous, ask a quick follow-up.
- Avoid “whole house” surprises.
- If the request affects more than 2 rooms, or uses words like “all”, “everywhere”, “house”, “downstairs”, ask for confirmation.
- Do what the user meant, not what they said literally.
- Example: “make it cozy” → turn on + dim + warm color temp.
- Be honest about execution.
- Only claim lights changed if you actually executed the API call (via Bash), or the user confirms they ran your curl.
- Prefer room-level control (
grouped_light) unless the user asks for a specific individual light.
Rooms vs zones (do not confuse these)
Hue has rooms and zones:
- A room contains lights.
- A zone groups multiple rooms (often “Downstairs/Upstairs/Beneden/Boven”), and zone lighting affects all its rooms.
Users often say “room” or “in ” when they really mean an area that could be either a room or a zone. Treat room/zone naming as interchangeable user language.
When the user gives a name (e.g. “Keuken”):
- Call
inventory.snapshot (one tool call).
- Normalize-match the name against both
result.rooms[].name and result.zones[].name.
- If it matches exactly one → proceed using the correct concept:
- room match → filter lights by
light.roomRid == room.rid
- zone match → collect
zone.roomRids[], then filter lights where light.roomRid is in that set
- If it matches both a room and a zone → ask which they meant.
- If it matches neither → ask a quick follow-up and show a few candidates from rooms + zones.
Gateway connection (defaults)
- Base URL (default):
http://hue-gateway:8000 (recommended when using docker sandboxd + shared network)
- Auth header (either works for
/v2/*):
Authorization: Bearer dev-token
X-API-Key: dev-key
Environment override knobs:
BASE_URL: Hue Gateway base URL.
HUE_AUTH_HEADER: full header line to use for auth (e.g. Authorization: Bearer ... or X-API-Key: ...).
HUE_TOKEN: bearer token value (used if HUE_AUTH_HEADER is unset).
HUE_API_KEY: API key value (used if HUE_AUTH_HEADER is unset).
Important: if you execute via a sandboxed Bash tool, localhost refers to the sandbox, not the host machine running Hue Gateway.
Important: Bash tool calls do not preserve shell state between tool invocations; keep base URL selection + actions in the same Bash call, or set BASE_URL explicitly each time.
Base URL selection (do this first)
If BASE_URL is not provided, try these in order until health succeeds:
http://hue-gateway:8000 (recommended when Hue Gateway is attached to the sandbox network)
http://host.docker.internal:8000 (common for Docker Desktop on macOS/Windows)
http://localhost:8000 (only works when executing on the same host/network namespace as the gateway)
Common mistakes (avoid)
- Do not use
localhost:8000 from a sandboxed Bash tool unless you know the gateway is in the same network namespace.
- Do not parse
result.data for clipv2.request; Hue resources are at result.body.data.
- Do not use
curl -f for /v2/actions calls (it hides useful JSON error bodies); use curl -sS.
- Prefer RID-based
grouped_light.set (names are often missing/ambiguous for grouped lights).
- Do not try to parse curl JSON with
python3 - <<'PY' ... json.load(sys.stdin) ... PY (stdin is already used for the
Python program). Use python3 -c ... <<<"$JSON" (or jq) instead.
Quick start (recommended path)
- Select
BASE_URL + ensure ready (fast; put this at the top of the same Bash tool call where you run actions):
set -euo pipefail
CURL_HEALTH='curl -fsS --connect-timeout 1 --max-time 2'
BASE_URL="${BASE_URL:-}"
if [ -z "$BASE_URL" ]; then
for base in "http://hue-gateway:8000" "http://host.docker.internal:8000" "http://localhost:8000"; do
if $CURL_HEALTH "$base/healthz" >/dev/null; then
BASE_URL="$base"
break
fi
done
fi
[ -n "$BASE_URL" ] || { echo "Hue Gateway not reachable from this environment. Set BASE_URL to a reachable base URL."; exit 1; }
BASE_URL="${BASE_URL%/}"
echo "Using BASE_URL=$BASE_URL"
READY_JSON="$($CURL_HEALTH "$BASE_URL/readyz")"
case "$READY_JSON" in
*'"ready":true'*|*'"ready": true'*) : ;;
*) echo "Hue Gateway is not ready (ready=false)."; exit 1 ;;
esac
AUTH_HEADER="${HUE_AUTH_HEADER:-}"
if [ -z "$AUTH_HEADER" ]; then
if [ -n "${HUE_API_KEY:-}" ]; then
AUTH_HEADER="X-API-Key: $HUE_API_KEY"
else
AUTH_HEADER="Authorization: Bearer ${HUE_TOKEN:-dev-token}"
fi
fi
- Discover inventory (normalized read model; preferred over raw CLIP resources):
curl -sS --connect-timeout 1 --max-time 8 -X POST "$BASE_URL/v2/actions" \
-H 'Content-Type: application/json' \
-H "X-Request-Id: demo-rooms-1" \
-H "$AUTH_HEADER" \
-d '{"requestId":"demo-rooms-1","action":"inventory.snapshot","args":{}}'
Optional helper: if this skill is installed under ./.skills (RemcoChat default), you can get a parsed list as:
bash ./.skills/hue-instant-control/scripts/list_rooms.sh
This prints: <room-name>\t<grouped_light_rid>\t<room_rid>.
- Set a named room (fast + verified) using a single v2 action:
bash ./.skills/hue-instant-control/scripts/room_set_by_name.sh --room "Woonkamer" --brightness 35 --color-temp-k 2400
- (Optional) Set a room by grouped-light RID using
grouped_light.set (RID-based; no guessing):
curl -sS --connect-timeout 1 --max-time 8 -X POST "$BASE_URL/v2/actions" \
-H 'Content-Type: application/json' \
-H "X-Request-Id: demo-gl-1" \
-H "$AUTH_HEADER" \
-d '{"requestId":"demo-gl-1","action":"grouped_light.set","args":{"rid":"<GROUPED_LIGHT_RID>","state":{"on":true,"brightness":35,"colorTempK":2400}}}'
Note: for clipv2.request responses, Hue resources are at result.body.data (not result.data).
- Set a named lamp / plug using
light.set (fast; no discovery needed):
curl -sS --connect-timeout 1 --max-time 8 -X POST "$BASE_URL/v2/actions" \
-H 'Content-Type: application/json' \
-H "X-Request-Id: demo-light-1" \
-H "$AUTH_HEADER" \
-d '{"requestId":"demo-light-1","action":"light.set","args":{"name":"Vibiemme","state":{"on":true}}}'
Optional helper script (handles base URL selection + readiness + auth):
bash ./.skills/hue-instant-control/scripts/light_set_by_name.sh --name "Vibiemme" --on true
- Apply a deterministic “vibe” preset (reduces LLM variability):
bash ./.skills/hue-instant-control/scripts/room_vibe.sh --room "Woonkamer" --vibe cozy
- Set a named zone (safe by default; requires
--confirm when it affects >2 rooms):
bash ./.skills/hue-instant-control/scripts/zone_set_by_name.sh --zone "Downstairs" --on false
bash ./.skills/hue-instant-control/scripts/zone_set_by_name.sh --zone "Downstairs" --on false --confirm
- List all lights in a named zone (read-only; first-time-right):
bash ./.skills/hue-instant-control/scripts/zone_list_lights.sh --zone "Beneden" --print-ok
- List lights in a named room (read-only; first-time-right):
bash ./.skills/hue-instant-control/scripts/room_list_lamps.sh --room "Woonkamer" --print-ok
When you need details
- Full reference (discovery flows, parsing patterns, vibe presets, verification, failure handling):
references/REFERENCE.md
Resources (Level 3)
- Health + readiness:
scripts/health_check.sh
- Room discovery:
scripts/list_rooms.sh
- Named lamp/plug control:
scripts/light_set_by_name.sh
- Named room control:
scripts/room_set_by_name.sh
- Vibe presets (room):
scripts/room_vibe.sh
- Named zone control:
scripts/zone_set_by_name.sh
- List zone lights (read-only):
scripts/zone_list_lights.sh
- List room lamps (read-only):
scripts/room_list_lamps.sh