About this project

Bose shut down the SoundTouch cloud, leaving speakers with Bluetooth, AUX, AirPlay and multiroom zones but no internet radio, presets, browsing or Alexa. This repository is a Claude Code skill that walks an owner through pointing their speakers at a self-hosted replacement service and getting radio and presets back. It assumes a non-technical user: the skill asks rather than instructs, reads freely, and requires confirmation before changing anything on a speaker. The replacement service is AfterTouch by gesellix (Bose-SoundTouch), which the skill credits as ground truth; this repo is a skill, not a fork, and installs the published container image. Requirements are one or more SoundTouch speakers on the local network, a Docker-capable machine on the same network (NAS, Raspberry Pi, small Linux box) with a stable address, plus Python 3.11+, uv and Docker with the compose plugin. The skill's first step checks these itself and reports what is missing with install lines. Installation is via the Claude Code plugin marketplace: /plugin marketplace add bitranox/soundtouch-decloud /plugin install soundtouch-decloud It can also be triggered by describing the problem in plain words, or invoked by name. The workflow runs in phases with check-ins: prerequisite check and installation help, speaker discovery, standing up the service, backing up every speaker before any change, rewriting the four service URLs, waiting for radio sources, recovering and verifying stations, writing presets, and finally proving playback by listening rather than counting. The skill ships five reference files and four scripts. Every script prints a JSON envelope and uses consistent exit codes (0 yes, 1 no, 2 could not tell); anything that changes a speaker requires an explicit --confirm, so read-only operations are always safe. Scripts cover preflight checks, Docker/compose validation and service health, network discovery, onboarding over the diagnostic SSH port with URL rewriting and reboot, and preset backup/harvest/validate/check/restore/relativize. The documentation calls out failure modes that are easy to misdiagnose: bridge networking appears installed but discovers nothing (host networking is required); rewriting only the account URL yields a speaker that registers and syncs but plays nothing; URL write order is load-bearing because persisting before writing saves old values while commands still answer OK; raw stream URLs in presets are accepted but never play, so presets use AfterTouch's relative form; a copied service keeps the old address via settings.json server_url; and a DHCP-assigned service address breaks every speaker at once later. Station recovery is a four-step process: harvest stream URLs from pre-migration presets (the service does not retain them, so backup runs first), ask the owner whether the old station list is still wanted, research remaining stations for current direct stream endpoints, and validate from the service host. Validation reports per button: audio, playlist, hls, not-audio, dead, or missing. The docs note that stations move and die, and that .m3u playlists can pass a naive audio check while containing no audio. For ongoing operation, the skill adds an off-service snapshot of each speaker's presets, a one-shot restore, and a read-only check suitable for scheduled alarming. It deliberately installs nothing that writes on its own, since AfterTouch v0.137.0 shares presets across speakers on an account. The docs cite measured data: a two-minute restore loop over 18.7 days made 11692 runs and wrote presets once, and one sleeping WiFi speaker produced 1303 unreadable readings while never being short of presets. The alarm distinguishes missing presets from an unresponsive speaker. Scripts are standard-library only so they run on a machine with nothing installed; pytest is the only test dependency. A repo conventions checker validates manifests, skill frontmatter, test coverage of shipped scripts and line endings, with CI on Linux, Windows and macOS. Licensed MIT.