Shelly
Use this skill for Shelly device inspection and guarded control through the
bundled helper. Keep the markdown instructions generic; API-specific request
construction belongs in shelly.cjs.
Core Contract
- Run Shelly HTTP operations through
skills/shelly/shelly.cjs. Do not
handcraft Shelly URLs or JSON bodies when the helper supports the operation.
- The helper executes HTTP operations through the HybridClaw gateway, so normal
Shelly reads and writes should be a single helper command. Use
--request
only when an explicit request specification is needed for debugging or code
review. For WebSocket planning outputs, use the emitted webSocket object as
the complete connection or message specification.
- Read state before any relay, switch, light, or cover control operation.
- Treat control operations as amber. Before asking for approval, build an
approval-plan for the selected operation and include its
approvedHelperCommandText in the approval request. Stop after presenting
the plan. Only after the operator confirms in a later message, run that
helper command exactly and use its emitted request specification unchanged.
- Do not perform factory reset, reboot, firmware update, Wi-Fi reset, auth
changes, or certificate upload through this skill.
Helper Operations
Use this command surface directly; do not rediscover flags by trial and error.
Run node skills/shelly/shelly.cjs --help only when the surface below appears
stale. The helper owns the Shelly API method, path, body selection, gateway
dispatch, secret injection, and response wrapping. Normal HTTP commands execute
the request and return command: "live", the operation, a redacted request
summary, and the gateway result. --request emits a request wrapper containing
command, operation, stakesTier, and httpRequest without executing it.
WebSocket helpers emit webSocket instead of httpRequest. approval-plan
emits no httpRequest; it validates an amber command and returns the exact
approved helper command to run after confirmation.
Command surface:
node skills/shelly/shelly.cjs [--format json|pretty] [--request] <resource> <action> [flags]
node skills/shelly/shelly.cjs [--format json|pretty] approval-plan <resource> <action> [flags]
device info --device-url http://192.0.2.10 [--ident]
device status --device-url http://192.0.2.10
device config --device-url http://192.0.2.10
device methods --device-url http://192.0.2.10
device components --device-url http://192.0.2.10 [--include status] [--include config] [--key switch:0]
cover config --device-url http://192.0.2.10 --id 0
cover status --device-url http://192.0.2.10 --id 0
cover open --device-url http://192.0.2.10 --id 0 --operator-grant
cover close --device-url http://192.0.2.10 --id 0 --operator-grant
cover stop --device-url http://192.0.2.10 --id 0 --operator-grant
cover goto --device-url http://192.0.2.10 --id 0 --position 50 --operator-grant
cover status --cloud-host https://<HOST> --device-id abc123
cover goto --cloud-host https://<HOST> --device-id abc123 --position 50 --operator-grant
switch status --device-url http://192.0.2.10 --id 0
switch set --device-url http://192.0.2.10 --id 0 --on true --operator-grant
switch toggle --device-url http://192.0.2.10 --id 0 --operator-grant
switch set --cloud-host https://<HOST> --device-id abc123 --on true --operator-grant
relay status --device-url http://192.0.2.10 --id 0
relay set --device-url http://192.0.2.10 --id 0 --turn on|off|toggle --operator-grant
light set --cloud-host https://<HOST> --device-id abc123 --on true --brightness 50 --operator-grant
cloud state --cloud-host https://<HOST> --device-id abc123 --select status
cloud all-status --cloud-host https://<HOST>
cloud oauth-token --cloud-host https://<HOST>
cloud websocket-url --cloud-host https://<HOST>
cloud websocket-command --cloud-host https://<HOST> --device-id abc123 --cmd roller_to_pos --params-json '{"id":0,"pos":50}' --operator-grant
gen1 get --device-url http://192.0.2.10 --path /settings [--query key=value]
gen1 set --device-url http://192.0.2.10 --path /settings/relay/0 --query default_state=on --operator-grant
rpc get --device-url http://192.0.2.10 --method Cloud.GetStatus [--param id=0] [--params-json '{}']
rpc call --device-url http://192.0.2.10 --method Cover.Calibrate --params-json '{"id":0}' --operator-grant
Supported operation groups:
- Device reads: local info, status, config, method list, and components; cloud
state when routed with cloud inputs.
- Generic Gen1 and Gen2 coverage: documented Gen1 HTTP paths and documented
Gen2 RPC methods.
- Cover reads/control: config, status, open, close, stop, and go-to-position.
- Switch and relay reads/control: status, set, and toggle where supported.
- Light control: cloud set operations.
- Cloud account reads and event planning: v2 state by known ids, OAuth token
exchange, Real Time Events all-status, WebSocket URL, and command-message
construction.
Selection Workflow
- Prefer local Gen2+ reads when a local device URL is available and reachable.
- Fall back to Gen1 reads for older devices.
- Use Real Time Events OAuth for account-level cloud discovery.
- Use Cloud Control API v2 for known device ids, especially when local access
is unavailable or the requested device is remote.
- For control, use the matching helper command and include
--operator-grant
only after explicit approval.
When the operator explicitly asks for local, LAN, or RPC access, stay on the
local helper route. If local execution fails, report the local failure and the
gateway error; do not substitute a cloud result unless the operator then asks
for a cloud fallback.
Required Inputs
Collect only the inputs needed for the chosen surface.
| Input |
Where it comes from |
Used for |
| Local device URL or IP |
Router/DHCP data, Shelly app network details, local DNS, or a verified URL |
Local Gen1/Gen2 reads and control |
| Cover or switch channel id |
Local component keys such as cover:0 or switch:0 |
Component-specific local/cloud operations |
| Shelly Cloud tenant server URI |
Shelly Smart Control user settings; OAuth JWT user_api_url can also identify it |
Cloud Control v2 and Real Time Events |
SHELLY_CLOUD_AUTH_KEY |
Shelly Smart Control user settings, Authorization Cloud Key |
Cloud Control v2 for known device ids |
| Device id |
Shelly Smart Control device details, Device Information, Device Id |
Cloud Control v2 state/control |
SHELLY_CLOUD_ACCESS_TOKEN |
Captured OAuth access token |
Real Time Events account discovery |
SHELLY_OAUTH_CODE |
Temporary OAuth authorization code from the callback URL |
One-time token exchange |
Access to Local Devices
Local device requests require the HybridClaw runtime to reach the device
network and the workspace network policy to allow the helper-emitted host,
port, method, and path. Operators can add policy rules through the CLI, the
local TUI/web /policy command, or the /admin/approvals network policy
editor. If local access is not available, use the cloud APIs or ask for a
reachable local device URL.
For Gen2+ RPC, authorize the method/path that the helper emits. Some local
reads and all local control operations use HTTP POST to a method-scoped
/rpc/<method> path, even when the RPC method itself is a read.
On macOS, the app that launches the gateway must have Local Network
permission. If local LAN calls fail with No route to host, EHOSTUNREACH,
or kernel log drops with reason: NECP, verify that a direct LAN curl from
the same terminal app can reach the Shelly device. Reset or grant Local Network
permission for that terminal app, reopen it, confirm direct LAN access, then
start the gateway from the allowed app session.
Credentials
- Store the Cloud Control v2 key as
SHELLY_CLOUD_AUTH_KEY.
- Store the Real Time Events OAuth token as
SHELLY_CLOUD_ACCESS_TOKEN.
- Store an OAuth authorization code as
SHELLY_OAUTH_CODE only long enough for
cloud oauth-token to exchange it and capture SHELLY_CLOUD_ACCESS_TOKEN.
- Never paste raw keys, access tokens, authorization codes, or local device
passwords into chat.
- Local Gen2+ devices with authentication enabled use Shelly digest
authentication. Prefer unauthenticated info endpoints, configured local auth
tooling, or cloud access rather than asking for local passwords in chat.
Discovery and Names
- Cloud Control API v2 requires known device ids and can request status and
settings for up to 10 ids at a time.
- Real Time Events all-status can discover account device statuses when
SHELLY_CLOUD_ACCESS_TOKEN is configured.
- Shelly names can exist in multiple layers: app display name, room assignment,
firmware device name, component name, and cloud metadata. Report the field
and API surface that supplied or omitted a name; do not treat a missing field
from one surface as proof that another naming layer is unset.
Result Handling
- Base status and control answers on successful live Shelly API results from
the current turn.
- For Real Time Events reads, the helper refreshes an invalid stored OAuth
access token once when
SHELLY_OAUTH_CODE is configured, then retries the
original read. Treat the final helper result as authoritative; do not ask for
device ids, LAN IPs, or manual re-auth until that retry path has failed.
- Inspect returned JSON and require
isok: true when that field is present.
- For cloud or local errors, report the operation, target, and upstream error
without inventing state.
- For local gateway errors, distinguish policy denials from outbound
connection failures. A 400 "not allowlisted" error is a workspace network
policy denial. A 502 "gateway policy accepted the request, but the gateway
process could not open the outbound connection" is not a policy denial.
- Do not claim container isolation, container networking, or
--network host
unless current hybridclaw gateway status shows the gateway is actually
running in container sandbox mode. If gateway status is not checked, describe
the failure only as a gateway process outbound connection failure.
- Respect Shelly Cloud rate limits; do not fan out or retry in tight loops.
API Surfaces
- Local Gen2+ devices use RPC methods under
/rpc; use the dedicated
noun-verb helpers for common operations and generic RPC helpers for other
documented methods.
- Local Gen1 devices use classic HTTP endpoints; use dedicated helpers for
common relay/status operations and generic Gen1 endpoint helpers for other
documented paths.
- Shelly Cloud Control API v2 uses a tenant server URI, an Authorization Cloud
Key, and known device ids for state and control.
- Shelly Real Time Events HTTP calls use OAuth/Bearer authorization and can
return account-level current or last-known device statuses. Real Time Events
WebSocket helpers emit connection and command-message specifications.
Official references:
Cloud Control API getting started,
Cloud Control API v2,
Cloud Real Time Events,
Gen2+ Shelly service,
Gen2+ Cover service,
Gen2+ Switch service,
Gen2+ authentication,
and Gen1 device API.
1---2name: shelly3description: Read and control Shelly smart relays, plugs, lights, covers, shutters, shades, sensors, and energy devices through local Gen1/Gen2 HTTP APIs, Shelly Gen2 RPC methods such as Cover.GetConfig and Cover.GetStatus, or the Shelly Cloud Control API with guarded output changes.4---56# Shelly78Use this skill for Shelly device inspection and guarded control through the9bundled helper. Keep the markdown instructions generic; API-specific request10construction belongs in `shelly.cjs`.1112## Core Contract1314- Run Shelly HTTP operations through `skills/shelly/shelly.cjs`. Do not15 handcraft Shelly URLs or JSON bodies when the helper supports the operation.16- The helper executes HTTP operations through the HybridClaw gateway, so normal17 Shelly reads and writes should be a single helper command. Use `--request`18 only when an explicit request specification is needed for debugging or code19 review. For WebSocket planning outputs, use the emitted `webSocket` object as20 the complete connection or message specification.21- Read state before any relay, switch, light, or cover control operation.22- Treat control operations as amber. Before asking for approval, build an23 `approval-plan` for the selected operation and include its24 `approvedHelperCommandText` in the approval request. Stop after presenting25 the plan. Only after the operator confirms in a later message, run that26 helper command exactly and use its emitted request specification unchanged.27- Do not perform factory reset, reboot, firmware update, Wi-Fi reset, auth28 changes, or certificate upload through this skill.2930## Helper Operations3132Use this command surface directly; do not rediscover flags by trial and error.33Run `node skills/shelly/shelly.cjs --help` only when the surface below appears34stale. The helper owns the Shelly API method, path, body selection, gateway35dispatch, secret injection, and response wrapping. Normal HTTP commands execute36the request and return `command: "live"`, the operation, a redacted request37summary, and the gateway result. `--request` emits a request wrapper containing38`command`, `operation`, `stakesTier`, and `httpRequest` without executing it.39WebSocket helpers emit `webSocket` instead of `httpRequest`. `approval-plan`40emits no `httpRequest`; it validates an amber command and returns the exact41approved helper command to run after confirmation.4243Command surface:4445```text46node skills/shelly/shelly.cjs [--format json|pretty] [--request] <resource> <action> [flags]47node skills/shelly/shelly.cjs [--format json|pretty] approval-plan <resource> <action> [flags]4849device info --device-url http://192.0.2.10 [--ident]50device status --device-url http://192.0.2.1051device config --device-url http://192.0.2.1052device methods --device-url http://192.0.2.1053device components --device-url http://192.0.2.10 [--include status] [--include config] [--key switch:0]54cover config --device-url http://192.0.2.10 --id 055cover status --device-url http://192.0.2.10 --id 056cover open --device-url http://192.0.2.10 --id 0 --operator-grant57cover close --device-url http://192.0.2.10 --id 0 --operator-grant58cover stop --device-url http://192.0.2.10 --id 0 --operator-grant59cover goto --device-url http://192.0.2.10 --id 0 --position 50 --operator-grant60cover status --cloud-host https://<HOST> --device-id abc12361cover goto --cloud-host https://<HOST> --device-id abc123 --position 50 --operator-grant62switch status --device-url http://192.0.2.10 --id 063switch set --device-url http://192.0.2.10 --id 0 --on true --operator-grant64switch toggle --device-url http://192.0.2.10 --id 0 --operator-grant65switch set --cloud-host https://<HOST> --device-id abc123 --on true --operator-grant66relay status --device-url http://192.0.2.10 --id 067relay set --device-url http://192.0.2.10 --id 0 --turn on|off|toggle --operator-grant68light set --cloud-host https://<HOST> --device-id abc123 --on true --brightness 50 --operator-grant69cloud state --cloud-host https://<HOST> --device-id abc123 --select status70cloud all-status --cloud-host https://<HOST>71cloud oauth-token --cloud-host https://<HOST>72cloud websocket-url --cloud-host https://<HOST>73cloud websocket-command --cloud-host https://<HOST> --device-id abc123 --cmd roller_to_pos --params-json '{"id":0,"pos":50}' --operator-grant74gen1 get --device-url http://192.0.2.10 --path /settings [--query key=value]75gen1 set --device-url http://192.0.2.10 --path /settings/relay/0 --query default_state=on --operator-grant76rpc get --device-url http://192.0.2.10 --method Cloud.GetStatus [--param id=0] [--params-json '{}']77rpc call --device-url http://192.0.2.10 --method Cover.Calibrate --params-json '{"id":0}' --operator-grant78```7980Supported operation groups:8182- Device reads: local info, status, config, method list, and components; cloud83 state when routed with cloud inputs.84- Generic Gen1 and Gen2 coverage: documented Gen1 HTTP paths and documented85 Gen2 RPC methods.86- Cover reads/control: config, status, open, close, stop, and go-to-position.87- Switch and relay reads/control: status, set, and toggle where supported.88- Light control: cloud set operations.89- Cloud account reads and event planning: v2 state by known ids, OAuth token90 exchange, Real Time Events all-status, WebSocket URL, and command-message91 construction.9293## Selection Workflow94951. Prefer local Gen2+ reads when a local device URL is available and reachable.962. Fall back to Gen1 reads for older devices.973. Use Real Time Events OAuth for account-level cloud discovery.984. Use Cloud Control API v2 for known device ids, especially when local access99 is unavailable or the requested device is remote.1005. For control, use the matching helper command and include `--operator-grant`101 only after explicit approval.102103When the operator explicitly asks for local, LAN, or RPC access, stay on the104local helper route. If local execution fails, report the local failure and the105gateway error; do not substitute a cloud result unless the operator then asks106for a cloud fallback.107108## Required Inputs109110Collect only the inputs needed for the chosen surface.111112| Input | Where it comes from | Used for |113| --- | --- | --- |114| Local device URL or IP | Router/DHCP data, Shelly app network details, local DNS, or a verified URL | Local Gen1/Gen2 reads and control |115| Cover or switch channel id | Local component keys such as `cover:0` or `switch:0` | Component-specific local/cloud operations |116| Shelly Cloud tenant server URI | Shelly Smart Control user settings; OAuth JWT `user_api_url` can also identify it | Cloud Control v2 and Real Time Events |117| `SHELLY_CLOUD_AUTH_KEY` | Shelly Smart Control user settings, Authorization Cloud Key | Cloud Control v2 for known device ids |118| Device id | Shelly Smart Control device details, Device Information, Device Id | Cloud Control v2 state/control |119| `SHELLY_CLOUD_ACCESS_TOKEN` | Captured OAuth access token | Real Time Events account discovery |120| `SHELLY_OAUTH_CODE` | Temporary OAuth authorization code from the callback URL | One-time token exchange |121122## Access to Local Devices123124Local device requests require the HybridClaw runtime to reach the device125network and the workspace network policy to allow the helper-emitted host,126port, method, and path. Operators can add policy rules through the CLI, the127local TUI/web `/policy` command, or the `/admin/approvals` network policy128editor. If local access is not available, use the cloud APIs or ask for a129reachable local device URL.130131For Gen2+ RPC, authorize the method/path that the helper emits. Some local132reads and all local control operations use HTTP `POST` to a method-scoped133`/rpc/<method>` path, even when the RPC method itself is a read.134135On macOS, the app that launches the gateway must have Local Network136permission. If local LAN calls fail with `No route to host`, `EHOSTUNREACH`,137or kernel log drops with `reason: NECP`, verify that a direct LAN `curl` from138the same terminal app can reach the Shelly device. Reset or grant Local Network139permission for that terminal app, reopen it, confirm direct LAN access, then140start the gateway from the allowed app session.141142## Credentials143144- Store the Cloud Control v2 key as `SHELLY_CLOUD_AUTH_KEY`.145- Store the Real Time Events OAuth token as `SHELLY_CLOUD_ACCESS_TOKEN`.146- Store an OAuth authorization code as `SHELLY_OAUTH_CODE` only long enough for147 `cloud oauth-token` to exchange it and capture `SHELLY_CLOUD_ACCESS_TOKEN`.148- Never paste raw keys, access tokens, authorization codes, or local device149 passwords into chat.150- Local Gen2+ devices with authentication enabled use Shelly digest151 authentication. Prefer unauthenticated info endpoints, configured local auth152 tooling, or cloud access rather than asking for local passwords in chat.153154## Discovery and Names155156- Cloud Control API v2 requires known device ids and can request status and157 settings for up to 10 ids at a time.158- Real Time Events all-status can discover account device statuses when159 `SHELLY_CLOUD_ACCESS_TOKEN` is configured.160- Shelly names can exist in multiple layers: app display name, room assignment,161 firmware device name, component name, and cloud metadata. Report the field162 and API surface that supplied or omitted a name; do not treat a missing field163 from one surface as proof that another naming layer is unset.164165## Result Handling166167- Base status and control answers on successful live Shelly API results from168 the current turn.169- For Real Time Events reads, the helper refreshes an invalid stored OAuth170 access token once when `SHELLY_OAUTH_CODE` is configured, then retries the171 original read. Treat the final helper result as authoritative; do not ask for172 device ids, LAN IPs, or manual re-auth until that retry path has failed.173- Inspect returned JSON and require `isok: true` when that field is present.174- For cloud or local errors, report the operation, target, and upstream error175 without inventing state.176- For local gateway errors, distinguish policy denials from outbound177 connection failures. A 400 "not allowlisted" error is a workspace network178 policy denial. A 502 "gateway policy accepted the request, but the gateway179 process could not open the outbound connection" is not a policy denial.180- Do not claim container isolation, container networking, or `--network host`181 unless current `hybridclaw gateway status` shows the gateway is actually182 running in container sandbox mode. If gateway status is not checked, describe183 the failure only as a gateway process outbound connection failure.184- Respect Shelly Cloud rate limits; do not fan out or retry in tight loops.185186## API Surfaces187188- Local Gen2+ devices use RPC methods under `/rpc`; use the dedicated189 noun-verb helpers for common operations and generic RPC helpers for other190 documented methods.191- Local Gen1 devices use classic HTTP endpoints; use dedicated helpers for192 common relay/status operations and generic Gen1 endpoint helpers for other193 documented paths.194- Shelly Cloud Control API v2 uses a tenant server URI, an Authorization Cloud195 Key, and known device ids for state and control.196- Shelly Real Time Events HTTP calls use OAuth/Bearer authorization and can197 return account-level current or last-known device statuses. Real Time Events198 WebSocket helpers emit connection and command-message specifications.199200Official references:201[Cloud Control API getting started](https://shelly-api-docs.shelly.cloud/cloud-control-api/),202[Cloud Control API v2](https://shelly-api-docs.shelly.cloud/cloud-control-api/communication-v2/),203[Cloud Real Time Events](https://shelly-api-docs.shelly.cloud/cloud-control-api/real-time-events/),204[Gen2+ Shelly service](https://shelly-api-docs.shelly.cloud/gen2/ComponentsAndServices/Shelly/),205[Gen2+ Cover service](https://shelly-api-docs.shelly.cloud/gen2/ComponentsAndServices/Cover/),206[Gen2+ Switch service](https://shelly-api-docs.shelly.cloud/gen2/ComponentsAndServices/Switch/),207[Gen2+ authentication](https://shelly-api-docs.shelly.cloud/gen2/General/Authentication/),208and [Gen1 device API](https://shelly-api-docs.shelly.cloud/gen1/).