Sonos Py
БесплатноНе проверенLocal Sonos controller: CLI and MCP server, no cloud required
Описание
Local Sonos controller: CLI and MCP server, no cloud required
README
Local Sonos controller — CLI and MCP server. No cloud, no account, no internet required.
Control your Sonos speakers directly over your LAN via a full-featured CLI or as an MCP server that exposes every capability as an AI tool.
Features
- Full CLI — discover, status, volume, playback, groups, favorites, radio, Apple Music, queue, alarms, snapshots, sleep timer
- MCP server — all features available as tools for LLM agents (stdio and streamable-HTTP transports)
- Favorites & playlists — play Sonos favorites, radio stations, and Apple Music by name (fuzzy match)
- Radio Browser — search and play any station from the radio-browser.info directory
- Apple Music — catalog search, share-link playback, alias bookmarks
- Snapshots — save and restore volume/source/group state
- Policy engine — volume caps, URL allowlists, confirmation guards
- Zero cloud — every command hits your speakers directly over UPnP/SoCo
Requirements
- Python 3.14+
- uv (recommended) or pip
- Sonos speakers on the same LAN (S1 or S2 firmware)
Installation
# from PyPI (once published)
pip install sonos-py
# from source
git clone https://github.com/jenreh/sonos-py
cd sonos-py
uv sync
The sonos command is available after install. Run sonos discover to verify your speakers are reachable.
Quick start
# Find all speakers on the network
sonos discover
# Show playback state for all rooms
sonos status
# Play a Sonos favorite (fuzzy name match)
sonos favorites play Büro "Lieblingstitel"
# Play a radio station by alias
sonos radio play Büro 1LIVE
# Adjust volume
sonos volume up Büro --step 10
# Pause / resume
sonos playback pause Büro
sonos playback play Büro
CLI reference
sonos [OPTIONS] COMMAND [ARGS]
Options:
--config-dir PATH Override config directory
--json Output JSON instead of rich tables
--dry-run Preview action without executing
--log-level TEXT Logging level [default: WARNING]
--refresh Force topology refresh before command
| Command group | Description |
|---|---|
discover |
Scan LAN for Sonos speakers |
rooms |
List speakers and their network info |
status [ROOM] |
Playback state for one room or all |
volume get/set/up/down |
Volume control (room / group / all scopes) |
mute / unmute |
Mute control |
playback play/pause/stop/next/previous |
Transport controls |
favorites list/play/refresh |
Sonos favorites |
radio search/play/bind/aliases |
Internet radio via Radio Browser |
apple auth/search/play/bind/aliases/enqueue |
Apple Music |
groups list/join/ungroup/isolate |
Group management |
queue list/clear/play |
Queue management |
alarms list/enable/disable/update/set |
Alarm clock management |
snapshot save/restore/list |
State snapshots |
sleep [ROOM] [SECONDS] |
Sleep timer (omit seconds to clear) |
config show |
Display current configuration |
doctor |
Diagnose config, storage, and network |
MCP server
# stdio (default — use with Claude Desktop or any MCP host)
sonos-mcp
# streamable-HTTP
sonos-mcp --transport streamable-http --port 8765
Add to claude_desktop_config.json:
{
"mcpServers": {
"sonos": {
"command": "sonos-mcp"
}
}
}
Available MCP tools
| Tool | Description |
|---|---|
sonos_list_speakers |
List all speakers |
sonos_list_groups |
List speaker groups |
sonos_get_state |
Playback state (one or all) |
sonos_set_volume / sonos_adjust_volume |
Volume control |
sonos_set_mute |
Mute / unmute |
sonos_transport |
play / pause / stop / next / previous |
sonos_play_favorite |
Play a Sonos favorite by name |
sonos_search_radio / sonos_play_radio |
Radio Browser search and playback |
sonos_search_apple_music / sonos_play_apple_music |
Apple Music |
sonos_group / sonos_ungroup / sonos_isolate |
Group management |
sonos_queue |
List, clear, or play from queue |
sonos_snapshot_save / sonos_snapshot_restore |
State snapshots |
sonos_sleep_timer |
Set or clear sleep timer |
sonos_list_alarms |
List household alarms |
sonos_discover |
Force network rediscovery |
MCP resources
| Resource URI | Content |
|---|---|
sonos://speakers |
All speaker metadata |
sonos://groups |
Current group topology |
sonos://state |
Live playback state |
sonos://capabilities |
Enabled features and transports |
sonos://config/policies |
Active policy limits |
sonos://radio/aliases |
Saved radio aliases |
sonos://apple-music/aliases |
Saved Apple Music aliases |
Configuration
Config lives at ~/.config/sonos-local/config.toml (created automatically on first run). Override the directory with SONSO_LOCAL_CONFIG_DIR.
[network]
hosts = [] # static IPs — leave empty for auto-discovery
discovery_timeout_seconds = 5
request_timeout_seconds = 9.5
[policies.volume]
max_room_volume = 70
max_group_volume = 60
max_all_volume = 40
[policies.playback]
allow_arbitrary_urls = false # block arbitrary stream URLs
block_private_network_urls = true
[policies.radio]
default_countrycode = "DE"
min_bitrate = 64
preferred_codecs = ["MP3", "AAC", "AAC+"]
# Optional room aliases
[rooms.buero]
sonos_names = ["Büro"]
aliases = ["büro", "buero", "office"]
# Optional radio aliases
[radio.aliases.einslive]
stationuuid = "9606f727-0601-11e8-ae97-52543be04c81"
preferred_name = "1LIVE"
aliases = ["einslive", "1live"]
Apple Music
Apple Music playback works in two modes:
| Mode | How to set up |
|---|---|
| Share links (default) | No credentials needed — paste music.apple.com share links |
| Catalog search | Requires a Developer Token and User Token — set apple_music.developer.enabled = true and configure keys |
# Check auth status
sonos apple auth
# Play via share link
sonos apple play Büro --url "https://music.apple.com/de/album/..."
# Search and play
sonos apple search "Olivia Rodrigo GUTS"
sonos apple play Büro "GUTS" --type album
[!NOTE] For catalog search and library access, add your Apple Developer team credentials under
[apple_music.developer]inconfig.toml. The user token is read from the env varSONSO_APPLE_MUSIC_USER_TOKENor from the system keychain.
Using as a Python library
SonsoLocalService is the single facade used by the CLI and MCP server. You can use it directly in your own async code:
import asyncio
from sonos.core.app import SonsoLocalService
from sonos.core.models import Scope, TransportCommand
async def main() -> None:
svc = SonsoLocalService() # reads ~/.config/sonos-local/config.toml
await svc.startup()
try:
# discover speakers
topology = await svc.discover()
print(f"Found {len(topology.speakers)} speaker(s)")
# list current state
states = await svc.get_state()
for s in states:
print(f"{s.name}: {s.playback_state}, vol={s.volume}")
# volume
await svc.set_volume("Büro", 20, Scope.ROOM)
await svc.adjust_volume("Büro", -5, Scope.GROUP)
# transport
await svc.transport("Büro", TransportCommand.PAUSE, Scope.GROUP)
await svc.transport("Büro", TransportCommand.PLAY, Scope.GROUP)
# play a Sonos favorite (fuzzy name match)
result = await svc.play_favorite("Büro", "1LIVE", Scope.GROUP, isolate=False)
print(result.ok, result.action)
# play a radio station by alias or search term
await svc.play_radio("Büro", "1LIVE", Scope.GROUP, isolate=False)
# group management
await svc.group(coordinator="Büro", members=["Schlafzimmer"])
await svc.ungroup(["Schlafzimmer"])
# snapshot: save and restore
snap = await svc.save_snapshot(["Büro"], name="before-party")
await svc.restore_snapshot(snap.snapshot_id)
# alarms
alarms = await svc.list_alarms()
for a in alarms:
print(f"alarm {a.alarm_id}: {a.time} enabled={a.enabled}")
finally:
await svc.shutdown()
asyncio.run(main())
Pass a custom config directory or a pre-built SonosLocalConfig object to the constructor:
from pathlib import Path
from sonos.core.app import SonsoLocalService
svc = SonsoLocalService(config_dir=Path("/etc/myapp/sonos"))
All methods raise sonos.core.errors.SonosError subclasses on failure — never raw SoCo or network exceptions:
| Exception | Code | Meaning |
|---|---|---|
TargetNotFoundError |
target_not_found |
Room or favorite not found |
NetworkError |
network_error |
Speaker unreachable |
PlaybackError |
playback_error |
UPnP playback failure |
InvalidInputError |
invalid_input |
Bad argument (time format, etc.) |
PolicyError |
policy_error |
Volume cap or URL policy blocked |
AmbiguousTargetError |
ambiguous_target |
Name matches multiple speakers |
Development
# Set up environment
task init
# Run tests
task test
# Lint and format
task lint
task format
# Type check
task typecheck
Tests require no real hardware. Live integration tests (marked sonos_live) need speakers on the network:
task test:live
Architecture
sonos/
├── cli/ # Typer CLI — one file per command group
├── core/
│ ├── app.py # SonsoLocalService — the single application facade
│ ├── sonos/ # SoCo backend (async wrapper + discovery + favorites)
│ ├── radio/ # Radio Browser client and resolver
│ ├── apple_music/ # Apple Music client (catalog + share links)
│ ├── config.py # Pydantic config model, TOML load/save
│ └── policy.py # Volume/playback/URL policy enforcement
├── mcp_server/ # FastMCP server — tools and resources
└── storage/ # aiosqlite — snapshots, radio aliases, Apple Music aliases
The SonsoLocalService is the single entry point used by both the CLI and the MCP server. All SoCo calls run in a thread pool via asyncio.to_thread; all domain exceptions are SonosError subclasses so callers never see raw library exceptions.
Установить Sonos Py в Claude Desktop, Claude Code, Cursor
unyly install sonos-pyСтавит в Claude Desktop, Claude Code, Cursor и VS Code — сам разбирается с npx, uvx и сборкой из исходников.
Впервые? Поставь CLI: curl -fsSL https://unyly.org/install | sh
Или настроить вручную
Выполни в терминале:
claude mcp add sonos-py -- uvx sonos-pyПошаговые гайды: как установить Sonos Py
FAQ
Sonos Py MCP бесплатный?
Да, Sonos Py MCP бесплатный — установка в пару кликов через Unyly без оплаты.
Нужен ли API-ключ для Sonos Py?
Нет, Sonos Py работает без API-ключей и переменных окружения.
Sonos Py — hosted или self-hosted?
Self-hosted: сервер запускается локально на твоей машине командой из раздела установки.
Как установить Sonos Py в Claude Desktop, Claude Code или Cursor?
Открой Sonos Py на unyly.org, выбери вкладку своего клиента (Claude Desktop, Claude Code, Cursor) и нажми Install — конфиг сгенерируется автоматически, без правки JSON.
Похожие MCP
GitHub
PRs, issues, code search, CI status
автор: GitHubFilesystem
Secure file operations with configurable access controls.
Memory
Knowledge graph-based persistent memory system.
Template MCP Server
A CLI tool to create a new Model Context Protocol server project with TypeScript support, dual transport options, and an extensible structure
автор: mcpdotdirectAmap Maps Mcp Server
MCP server for using the AMap Maps API
автор: duxiaohuiSupabase
Database, auth and storage
автор: SupabaseEverything
Reference / test server with prompts, resources, and tools.
Git
Tools to read, search, and manipulate Git repositories.
Sequential Thinking
Dynamic and reflective problem-solving through thought sequences.
Time
Time and timezone conversion capabilities.
Compare Sonos Py with
Не уверен что выбрать?
Найди свой стек за 60 секунд
Автор?
Embed-бейдж для README
Похожее
Все в категории development
