{"id":"1e662797-8be7-4222-9f67-98ae3e3a7531","slug":"opensonos","kind":"mcp","name":"opensonos","summary":"Sonos core in Swift: any speaker as a soundbar satellite (incl. fronts), every room as an AirPlay target (S1 too), plus an MCP server.","owner":"omerkunul","repoUrl":"https://github.com/omerkunul/opensonos","license":"MIT","licenseTier":"permissive","trust":"community","stars":1,"match":null,"fewStars":true,"format":"mcp","createdAt":"2026-10-22T12:27:41.000Z","addedAt":"2026-10-29T00:49:16.790Z","logoUrl":"https://avatars.githubusercontent.com/u/288700?v=4","linkOnly":false,"collection":null,"skillPath":null,"categories":["cloud-infra","memory-knowledge"],"tags":["airplay","raop","sonos","swift","upnp"],"runtime":"binary","local":true,"cloudCapable":false,"cloudCapability":"unknown","cloudReadyOnPlatform":false,"needsApiKey":false,"reviewed":false,"syncedAt":"2026-10-29T00:49:35.536Z","sample":false,"url":"https://conduits.dev/tools/opensonos","language":"Swift","transports":["stdio"],"install":{},"requirements":{"env":[],"upstreamMayCharge":false},"tools":null,"readme":"# OpenSonos\n\nThe core of a Sonos controller, in Swift, with no app attached. Two things it does that the\nofficial app can't:\n\n- **Any speaker as a satellite.** Bond any Sonos speaker to a soundbar as sub, rear *or front*\n  left/right (for example two Play:1s as fronts). The soundbar can be an old Playbar.\n- **Every room as an AirPlay target, S1 included.** Each room shows up on its own in the\n  AirPlay menu of an iPhone or Mac, including S1-only and gen-1 players that never had\n  AirPlay. One sender can play in rooms on different systems (S1 + S2) at the same time.\n\nIt also ships an **MCP server**, so an AI assistant (Claude Code, Claude Desktop, or any MCP\nclient) can list rooms, plan a satellite layout and run the AirPlay bridge.\n\nThere are no apps in this repo. It is the logic, as a SwiftPM package you can drop into\nyour own project.\n\n| Product | What it is |\n|---|---|\n| `SonosKit` | Library: discovery, topology, bonding planner and runner, transport/volume/EQ, backups, AirPlay receiver and bridge |\n| `opensonos-mcp` | MCP server on stdio |\n| `opensonos` | Command line: `discover`, `airplay` |\n\nRequires macOS 15 / iOS 18 and Swift 6. Everything talks to the speakers directly on the\nlocal network (UPnP on port 1400). No cloud, no account.\n\n## Quick start\n\n```sh\nswift build -c release\n.build/release/opensonos discover       # list systems, rooms, devices, roles\n.build/release/opensonos airplay        # every room appears in the AirPlay menu\n```\n\nAs a library:\n\n```swift\n.package(url: \"https://github.com/omerkunul/opensonos.git\", branch: \"main\")\n// target dependency: .product(name: \"SonosKit\", package: \"opensonos\")\n```\n\n```swift\nimport SonosKit\n\nlet client = SOAPClient()\nlet systems = await Discovery.systems(await Discovery.discover(client: client))\nlet hh = try await client.loadHousehold(systems[0].seed)\n\n// Two Play:1s as front left/right of the Playbar, Sub kept:\nlet bar = hh.rooms.values.first { $0.kind == .homeTheater }!.primary\nlet steps = Planner.layout(hh, bar: bar, assignments: [\n    subUUID: .sub, leftUUID: .frontLeft, rightUUID: .frontRight,\n])\nfor step in steps { print(step.describe(hh)) }        // read-only so far\ntry BackupStore().save(hh, label: \"before fronts\")    // always back up first\n_ = try await Bonder(client: client).run(steps, on: hh)\n```\n\n```swift\n// AirPlay for every room, as long as the process runs:\nlet hub = AirPlayHub()\nawait hub.refresh()\nhub.keepFresh()\n```\n\n## Docs\n\n- [Architecture](docs/architecture.md): how the pieces fit\n- [Adding satellites](docs/satellites.md): channel tokens, the planner, the bonding quirks\n- [AirPlay to Sonos](docs/airplay.md): RAOP receiver, decryption, ALAC, re-streaming, gen-1 MP3\n- [MCP server](docs/mcp.md): setup and tools\n\n## Safety\n\nBonding rebuilds a home theater. Speakers drop out for a few seconds while they rebond,\nand the bar's surround settings get reset; the bonder restores them afterwards. Save a\n`BackupStore` snapshot first so `Planner.restore` can put things back. The MCP tools do\nthat for you, refuse to bond without `confirm: true`, and cap volume at\n`OPENSONOS_MAX_VOLUME`.\n\n## License\n\nMIT, see [LICENSE](LICENSE). `Sources/CShine` is the shine MP3 encoder under LGPL v2; see\n[NOTICE](NOTICE).\n\nNot affiliated with or endorsed by Sonos, Inc. or Apple Inc. \"Sonos\" and \"AirPlay\" are\ntrademarks of their owners and are used here only to describe compatibility.\n"}