# Alexa

> Expose HybridClaw as a custom Alexa skill and prepare guarded Alexa smart-home/device control payloads without exposing Amazon credentials.

- Skill: `hybridaione/alexa` (Agent Skill, multi-file: 3 files)
- Install (CLI): `npx skillmds@latest add hybridaione/alexa`
- Raw SKILL.md: https://api.skillmd.com/api/skills/hybridaione/alexa/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: HybridAIOne (https://skillmd.com/u/hybridaione)
- Updated: 2026-09-21
- Page: https://skillmd.com/skills/hybridaione/alexa

---


# Alexa

Use this skill for Amazon Alexa workflows in two narrow modes:

1. Expose HybridClaw as a custom Alexa skill through the Alexa Skills Kit (ASK).
2. Prepare guarded Alexa-as-device reads and write plans for the official Smart
   Home Skill API and the opt-in community Alexa Remote / `alexapy` surface.

Do not use this skill for arbitrary Amazon API calls, shopping account access,
or browser automation. Keep all credentials behind SecretRef and use the helper
to build bounded payloads instead of hand-writing URLs, headers, cookies, or
request bodies.

## Safety Rules

1. Validate every inbound ASK request before parsing slots or running an agent
   bridge. Reject invalid `Signature`, invalid `SignatureCertChainUrl`, signing
   certificates that do not cover `echo-api.amazon.com`, or timestamp drift of
   150 seconds or more.
2. Never persist or echo Login with Amazon access tokens. The request token maps
   to a HybridClaw operator session outside the prompt through the F13 SecretRef
   rail.
3. Model output sent back to Alexa must be TTS-safe. Use `build-response` so
   markdown, code blocks, and very long URLs are stripped before SSML is built.
4. Path-B reads are green but privacy-sensitive because devices, list contents,
   routines, and last-command history can reveal household behavior.
5. Path-B writes are amber/red. Announcements, list mutations, device control,
   and routine triggers require exact F8/F14 approval that names the target room
   or device and the action.
6. Stop after the first `401`, `403`, or `INVALID_AUTHORIZATION_CREDENTIAL`
   response. Emit or surface `event: alexa.relink_required`; do not retry-loop.
7. The community cookie path is reverse-engineered and can break when Amazon
   changes web/API behavior. Treat it as opt-in and operationally brittle.
8. Do not accept Amazon passwords, refresh cookies, LWA tokens, or Smart Home
   tokens in chat or CLI flags. Store them with `hybridclaw secret set ...`.

## Command Contract

Show helper usage:

```bash
node skills/alexa/alexa.cjs --help
```

Validate an inbound ASK request body exactly as received by the HTTPS endpoint:

```bash
node skills/alexa/alexa.cjs --format json verify-request \
  --request-body /tmp/alexa-request.json \
  --signature-cert-url "$SIGNATURE_CERT_CHAIN_URL" \
  --signature "$SIGNATURE"
```

Exchange a linked Alexa account token for a HybridClaw operator-session handle
outside model-visible output:

```bash
node skills/alexa/alexa.cjs --format json account-link-session \
  --request-body /tmp/alexa-request.json
```

Parse a validated ASK request envelope into a bounded agent bridge:

```bash
node skills/alexa/alexa.cjs --format json parse-request \
  --request-body /tmp/alexa-request.json
```

Build a voice-safe ASK response:

```bash
node skills/alexa/alexa.cjs --format json build-response \
  --speech "On it. I'll text you when it's done." \
  --reprompt "Anything else?"
```

Run Smart Home Skill API calls through the helper:

```bash
node skills/alexa/alexa.cjs --format json run smarthome-discover

node skills/alexa/alexa.cjs --format json run smarthome-state \
  --endpoint-id light-kitchen

node skills/alexa/alexa.cjs --format json plan smarthome-control \
  --endpoint-id light-kitchen \
  --action TurnOn

node skills/alexa/alexa.cjs --format json run smarthome-control \
  --endpoint-id light-kitchen \
  --action TurnOn \
  --operator-grant approve-alexa-write

node skills/alexa/alexa.cjs --format json plan smarthome-control \
  --endpoint-id thermostat-hallway \
  --action SetTargetTemperature \
  --temperature 20.5
```

Run community Alexa Remote / `alexapy` reads through the helper:

```bash
node skills/alexa/alexa.cjs --format json run devices \
  --amazon-domain amazon.de

node skills/alexa/alexa.cjs --format json run shopping-list
node skills/alexa/alexa.cjs --format json run todo-list
node skills/alexa/alexa.cjs --format json run last-commands
node skills/alexa/alexa.cjs --format json run dnd-state --device living-room
```

For Alexa-connected smart plugs/lights exposed through the Alexa app (for
example `Poolpumpe`), use the `smart-home` helper commands. Do not use
`connectedhomes/v1/appliances`; Amazon can return a 200 HTML deeplink page
instead of JSON. The helper resolves the Alexa app device by name, runs the
discovery and status/control calls itself, and returns the result JSON. This
path uses `ALEXA_REFRESH_COOKIE`; do not ask for
`ALEXA_SMARTHOME_ACCESS_TOKEN` or Smart Home Skill OAuth when the operator asks
to use the stored Alexa cookie for these Alexa-app appliances. If the helper
reports `Unauthenticated call`, `FORBIDDEN`, `INVALID_AUTHORIZATION_CREDENTIAL`,
or an HTTP 401/403, treat that as an auth failure for the cookie path. Inspect
the stored cookie/import path first; do not immediately start the browser proxy
unless the operator explicitly asks for a new proxy login.

```bash
node skills/alexa/alexa.cjs --format json smart-home status \
  --name Poolpumpe \
  --amazon-domain amazon.de

node skills/alexa/alexa.cjs --format json smart-home plan-control \
  --name Poolpumpe \
  --action off \
  --amazon-domain amazon.de

node skills/alexa/alexa.cjs --format json smart-home control \
  --name Poolpumpe \
  --action off \
  --amazon-domain amazon.de \
  --operator-grant approve-alexa-red-write
```

Prepare guarded community writes. First show the approval text to the operator.
After explicit approval, run the exact `approvedCommand` unchanged.
For Echo music playback, first call `run devices`, find the matching
`accountName` (for example `OK Computer`), then pass its `serialNumber`,
`deviceType`, and `deviceOwnerCustomerId` to `music-play`.

```bash
node skills/alexa/alexa.cjs --format json plan announce \
  --device living-room \
  --text "Package delivered."

node skills/alexa/alexa.cjs --format json run announce \
  --device living-room \
  --text "Package delivered." \
  --operator-grant approve-alexa-write

node skills/alexa/alexa.cjs --format json plan music-play \
  --device "<serialNumber from devices>" \
  --device-name "OK Computer" \
  --device-type "<deviceType from devices>" \
  --customer-id "<deviceOwnerCustomerId from devices>" \
  --query "Münchner Freiheit" \
  --provider AMAZON_MUSIC \
  --amazon-domain amazon.de

For exact song requests, do not concatenate artist and title into `--query`.
Pass the song title and artist separately so the helper can build a
locale-aware Alexa search phrase:

```bash
node skills/alexa/alexa.cjs --format json plan music-play \
  --device "<serialNumber from devices>" \
  --device-name "OK Computer" \
  --device-type "<deviceType from devices>" \
  --customer-id "<deviceOwnerCustomerId from devices>" \
  --song "Junge Römer" \
  --artist "Falco" \
  --provider APPLE_MUSIC \
  --amazon-domain amazon.de
```

node skills/alexa/alexa.cjs --format json run music-play \
  --device "<serialNumber from devices>" \
  --device-name "OK Computer" \
  --device-type "<deviceType from devices>" \
  --customer-id "<deviceOwnerCustomerId from devices>" \
  --query "Münchner Freiheit" \
  --provider AMAZON_MUSIC \
  --amazon-domain amazon.de \
  --operator-grant approve-alexa-write
```

Use `voice-command` only as a last-resort equivalent of typing/speaking a
command into Alexa, because it can trigger arbitrary Alexa behavior. Prefer
specific helpers such as `music-play`, `announce`, list actions, routines, or
Smart Home directives when they cover the task.

```bash
node skills/alexa/alexa.cjs --format json plan voice-command \
  --device "<serialNumber from devices>" \
  --device-name "OK Computer" \
  --device-type "<deviceType from devices>" \
  --customer-id "<deviceOwnerCustomerId from devices>" \
  --voice-command "play Münchner Freiheit" \
  --amazon-domain amazon.de

node skills/alexa/alexa.cjs --format json run voice-command \
  --device "<serialNumber from devices>" \
  --device-name "OK Computer" \
  --device-type "<deviceType from devices>" \
  --customer-id "<deviceOwnerCustomerId from devices>" \
  --voice-command "play Münchner Freiheit" \
  --amazon-domain amazon.de \
  --operator-grant approve-alexa-red-write
```

```bash
node skills/alexa/alexa.cjs --format json run shopping-list-add \
  --item milk \
  --operator-grant approve-alexa-write

node skills/alexa/alexa.cjs --format json run shopping-list-complete \
  --item-id item-123 \
  --operator-grant approve-alexa-write

node skills/alexa/alexa.cjs --format json run todo-list-add \
  --item "call plumber" \
  --operator-grant approve-alexa-write

node skills/alexa/alexa.cjs --format json run todo-list-complete \
  --item-id item-456 \
  --operator-grant approve-alexa-write

node skills/alexa/alexa.cjs --format json run routine-trigger \
  --routine evening \
  --operator-grant approve-alexa-write
```

Use `http-request ...` only as a debugging dry run when you need to inspect the
gateway-ready request object. For normal reads and writes, use `run ...` so the
CJS owns endpoint selection, headers, CSRF handling, execution, and result
reporting. When `run ...` returns `ok: true` and `outcome: "accepted"`, treat
the operation as accepted even if Alexa's response body is `{}`. Do not infer
an auth failure from an empty successful response body. For `music-play`,
`accepted` only means Alexa accepted the playback request. Do not tell the
operator the requested song is now playing unless the result includes
successful verification or a separate read confirms the selected track.

## Required Setup

Set or update required secrets in this order:

1. Browser admin: open the active HybridClaw admin URL ending in `/admin/secrets`.
2. Browser `/chat` or TUI fallback with `/secret set NAME value`.
3. Local console fallback with `hybridclaw secret set NAME value`.

Path A custom ASK skill local-console examples:

```bash
hybridclaw secret set ALEXA_ASK_SKILL_ID "amzn1.ask.skill.<uuid>"
hybridclaw secret set ALEXA_LWA_CLIENT_ID "amzn1.application-oa2-client.<id>"
hybridclaw secret set ALEXA_LWA_CLIENT_SECRET "<lwa client secret>"
```

Path B Smart Home Skill API local-console examples:

```bash
hybridclaw secret set ALEXA_SMARTHOME_CLIENT_ID "<smart-home oauth client id>"
hybridclaw secret set ALEXA_SMARTHOME_CLIENT_SECRET "<smart-home oauth client secret>"
hybridclaw secret set ALEXA_SMARTHOME_REFRESH_TOKEN "<refresh token>"
```

Path B community Alexa Remote / `alexapy` surface local-console example:

```bash
hybridclaw secret set ALEXA_AMAZON_DOMAIN "amazon.de"
```

Use HybridClaw or slash commands for operator setup. Do not ask the operator to
install or run external auth tools.

Start a local session and invoke the Alexa skill:

```bash
hybridclaw tui
```

Then use these prompts:

```text
/alexa set up Echo control for amazon.de and store the cookie
/alexa list my Alexa devices for amazon.de
/alexa play Münchner Freiheit on OK Computer
```

For a CLI-only operator, the same requests can be sent through any HybridClaw
channel that supports slash skill invocation:

```text
/skill alexa set up Echo control for amazon.de and store the cookie
/skill alexa list my Alexa devices for amazon.de
/skill alexa play Münchner Freiheit on OK Computer
```

Status-only prompts such as `/skill alexa status for amazon.de` are read-only.
For those prompts, inspect stored credentials and detached setup state, but do
not start a new auth proxy. If credentials are missing, tell the operator to run
the setup prompt explicitly.

When handling the setup prompt, run the bundled auth helper from the agent
workspace. First check live detached setup state:

```bash
node skills/alexa/alexa-auth.cjs --format json status --domain amazon.de
```

If that status returns `exists: true`, `processAlive: true`, `state:
"listening"`, and a `proxyUrl`, return that exact `proxyUrl` to the operator
instead of starting another proxy. Ignore recalled URLs, prior slash output, and
session transcript text unless they match the current live status. Never print a
proxy URL that did not come from the current helper output.

For slash handling, use detached mode so the local browser proxy survives while
the operator completes Amazon login, OTP, and CVF pages across turns:

```bash
node skills/alexa/alexa-auth.cjs setup --domain amazon.de --write-secret --detach --timeout-ms 600000
```

If the operator reports Amazon's "Wir können deine Handynummer nicht
verifizieren" challenge on a `127.0.0.1:<port>` proxy URL, do not reuse that
proxy. Stop the stale process if it is still alive, then start a fresh detached
setup on `localhost` so the browser uses a separate local cookie jar:

```bash
node skills/alexa/alexa-auth.cjs setup --domain amazon.de --write-secret --detach --timeout-ms 600000 --proxy-host localhost
```

Return the `proxyUrl` from the helper output to the operator. When the operator
comes back after login, check the same setup with:

```bash
node skills/alexa/alexa-auth.cjs status --domain amazon.de
```

Do not keep the setup proxy alive with ad hoc shell process management.
Detached mode is the supported lifecycle: it writes a status file, keeps the
proxy process alive after the slash turn ends, and stores the secret itself
after Amazon returns the token.

If invoking non-detached foreground setup through a shell tool, set that tool
timeout to at least `600000` ms too. Browser login, OTP, CAPTCHA, and Safari
handoff regularly take longer than 60 seconds; killing the shell command also
kills the local proxy and produces Safari errors such as "server unexpectedly
closed the connection" on `127.0.0.1:<port>/www.amazon.com/ap/signin`.

The bundled helper owns the browser proxy and token callback. It uses Amazon's
device-login domain rules: western marketplaces such as `amazon.de` must use
`amazon.com` as the auth proxy base while the target Alexa marketplace remains
`amazon.de`. Routing the device-login URL through `amazon.de` produces Amazon's
"Suchst du etwas?" 404 page. If the browser shows that 404 at the local proxy
URL, stop that run and restart through `alexa-auth.cjs`.

The helper starts Amazon's Alexa device-login flow on a local callback port,
captures the resulting `Atnr|...` refresh token, exchanges it for Alexa Remote
cookies through Amazon's token exchange endpoint, verifies the account against
the regional Alexa Remote API (`layla.amazon.com` for `amazon.de`), stores
`ALEXA_REFRESH_COOKIE` when requested, and returns device metadata. Re-run the
same slash setup prompt when Amazon expires the stored cookie. Port `8080` is
preferred for compatibility with the cookie helper, but HybridClaw automatically
uses another free local port when `8080` is already occupied.

If using HybridClaw's direct `http_request` helper path instead of invoking
the browser setup flow, `ALEXA_REFRESH_COOKIE` must be the complete `Cookie`
header for an authenticated Alexa Remote API request such as
`https://alexa.amazon.de/api/devices-v2/device`. A single cookie value such as
`session-id` or `ubid-main` is not enough. Do not paste Amazon passwords,
one-time codes, or raw tokens into chat; store only the resulting cookie header
through the HybridClaw secret store. The `alexa-auth.cjs import-cookie` helper
can store a cookie with `--write-secret` when a local JSON file, copied cURL
request, raw headers file, or raw text file exposes a recognizable full cookie
header. Use this fallback when Amazon's device-login proxy is blocked by CVF
phone verification but the operator can log into Amazon normally in a browser.

Use the community credentials only for operator-approved, opt-in workflows.
Amazon OTP or CAPTCHA prompts require F14 2FA handover. The helper output uses
`<secret:...>` placeholders and SecretRef names, never cleartext values.

## References

- Alexa Skills Kit overview:
  <https://developer.amazon.com/en-US/docs/alexa/ask-overviews/build-skills-with-the-alexa-skills-kit.html>
- ASK request and response JSON:
  <https://developer.amazon.com/en-US/docs/alexa/custom-skills/request-and-response-json-reference.html>
- ASK web service signature and timestamp validation:
  <https://developer.amazon.com/en-US/docs/alexa/custom-skills/host-a-custom-skill-as-a-web-service.html>
- Account linking with Login with Amazon:
  <https://developer.amazon.com/en-US/docs/alexa/account-linking/understand-account-linking.html>
- Smart Home Skill API:
  <https://developer.amazon.com/en-US/docs/alexa/smarthome/understand-the-smart-home-skill-api.html>
- ASK SDK for Node.js:
  <https://github.com/alexa/alexa-skills-kit-sdk-for-nodejs>
- `alexapy`:
  <https://gitlab.com/keatontaylor/alexapy>

