# mopidy-spotify: streaming Spotify through Mopidy

> mopidy-spotify lets a Mopidy music server play Spotify, which is useful if your music lives in Spotify and you want it in a Mopidy playlist, on a network player, or in a house full of speakers Mopidy drives. It is also a project whose readme leads with three warnings about what Spotify has recently changed, which is the most honest thing about it.

**mopidy/mopidy-spotify** — Mopidy extension for playing music from Spotify

- Repository: https://github.com/mopidy/mopidy-spotify
- Website: https://mopidy.com/ext/spotify/
- Stars: 986 · Forks: 111
- Language: Python
- License: Apache-2.0
- Published: 2026-10-20 · Updated: 2026-10-20 · Language: en
- Canonical page: https://hysenlabs.com/projects/mopidy-mopidy-spotify

## Three warnings, and they come first

The status section opens with three warnings, and they tell you more about the state of this project than any feature list would.

The first is that Spotify has recently disabled streaming via third-party access tokens, of the kind Mopidy-Spotify uses. The documented workaround is to obtain a new credentials file using librespot and put it where the extension expects it, with a link to the issue discussion for the details.

The second is that Spotify has introduced refresh token expiration, described in a developer blog post from June 2026. In practice it means you will have to re-authenticate every six months going forward.

The third is that Spotify has disabled username and password login for playback, so the extension now uses access token login and you no longer need to provide your Spotify account username or password.

Put together, those three warnings describe a project that is fighting an upstream service that keeps changing the terms of access, and is honest about it in the first screen of the documentation. That is worth something to an evaluator, because the alternative is discovering the same three things one broken afternoon at a time.

The six-month re-authentication cycle is the one to plan for. A server that quietly stops playing music is the kind of failure that gets noticed at the worst moment, and the readme's own remedy is to re-run the authorisation command when access expires or is revoked.

## What works, and what does not

The feature list is split into two, and the split is the honest part.

What works is playback, search, playlists in read-only mode, the top lists and Your Music in read-only mode, and lookup by URI.

What does not work is seeking, gapless playback, volume normalization, saving items to My Music, podcasts, radio, and Spotify Connect.

Two of those carry notes that make them less absolute. Saving to My Music is marked as possible via the web API, and podcasts are marked as now possible. Radio is marked with a question mark, which reads more like an open question than a commitment.

The gaps are worth understanding rather than treating as a list of bugs. Mopidy-Spotify is a control surface that talks to Spotify's API for metadata and a GStreamer element for the audio, and each gap is a place where one of those two has no way to express the feature. Seeking is the classic example. Gapless and volume normalization are audio pipeline features that the extension cannot apply to a stream it does not encode.

Read-only playlists are a limitation of the API surface, and it is worth knowing before you plan a household around this extension. Spotify Connect being absent is the more surprising gap, since that is exactly the feature that would let you hand playback over to another device in the house, and its absence means the Mopidy server has to be the only thing playing.

## The GStreamer plugin is the part you have to build

The dependency section explains that playback is not implemented by the extension itself.

You need the GStreamer Spotify plugin, a Rust plugin for Spotify playback based on librespot. The readme notes that the plugin is not yet available from the Mopidy apt repository, so it must either be built from source or installed from Debian packages that are available for some platforms. And there is a preference stated: the project currently prefers a forked version of the plugin that provides better logging, with the details in the release notes.

That is a lot of assembly for what looks like a small feature, and it is the reality of this project. The Python extension handles the API, the search, the playlists and the authentication, and the actual audio comes out of a GStreamer element that talks to Spotify using librespot's protocol implementation. If you have a GStreamer pipeline in your head, the mental model is that the extension is a control surface and the element is the transport.

The plugin is verifiable, which is useful when a build goes wrong. You can check that it is installed and what version it is with a one line command that pipes the element inspection output through a filter:

```sh
gst-inspect-1.0 spotifyaudiosrc | grep Version | awk '{print $2}'
```

So the practical order for a new installation is to get the element in place and check its version first, then install the Python extension, and only then fight with authentication.

## Authorisation in the browser, and where the token lives

The configuration section has been rewritten around a browser based authorisation flow, and the details are specific enough to follow.

Before starting Mopidy, you authorise the extension to access your Spotify library:

```sh
mopidy spotify auth web
```

You open the displayed URL, approve access in Spotify, and paste the result shown by the browser back into the terminal. Then you start Mopidy, and you run the command again if the access expires or is revoked. The readme is careful about what this authorises: it authorises library access, not playback.

Where the token is stored is the next decision. The command prefers your operating system keyring, and if the token cannot be saved in the keyring it warns before falling back to a local plaintext file protected by file permissions. There is a storage option that requires keyring storage rather than allowing the fallback, and for headless Linux services the readme points at the keyring project's own setup guide, which is the usual D-Bus secret service problem.

The user detail matters and is easy to get wrong. Run the command as the same operating system user that runs Mopidy, with the same configuration. If Mopidy runs as a system service, the command has to be run with the control utility instead:

```sh
sudo mopidyctl spotify auth web
```

There is also a logout command to clear the library authorisation and the cached playback credentials, and a legacy mode that switches back to the old authentication server, which was run by a Mopidy maintainer and is used by the old client id and secret settings. The readme recommends removing those two settings, and warns that the extension will not fall back to them automatically, that the legacy flag records your choice even when the settings are missing, and that a restart is needed to switch immediately.

## The configuration values, and one of them contradicts the feature list

The configuration section is a list of settings, and the values are mostly unsurprising.

The extension can be disabled, and the bitrate is 96, 160 or 320 kilobits with 160 as the default. The timeout is how many seconds to wait for search results and the like, defaulting to 10. Caching is allowed by default, the cache living in a spotify directory inside Mopidy's own cache directory, with a maximum size of 8192 mebibytes and zero meaning unlimited. Playlists can be hidden, and the search result counts for albums and artists are separately configurable.

The contradiction worth flagging is the volume normalization setting. There is a configuration value for whether volume normalization is active, and it defaults to true, while the feature list says volume normalization is not supported. The likely reading is that the setting is a preference passed to the Spotify service, which normalises on its side, rather than something the extension implements locally. If you are debugging a volume inconsistency, that is the distinction to keep in mind, and the documentation does not spell it out.

Otherwise the settings are a well behaved set: a few booleans with sensible defaults, an integer range for the search counts, and a cache size you are expected to think about on a small machine.

## The packaging tells you the floor, and the project is young

The manifest is short and tells you the constraints.

The project requires Python 3.13 or later, and depends on filelock, Mopidy 4.0.0 or later, pykka and requests, with the keyring as an optional extra. It registers itself through the Mopidy extension entry point group, so installing it is all that is needed for Mopidy to find it. The version is dynamic, resolved from version control by setuptools-scm, and the build uses setuptools.

The development tooling is a modern set: tox with tox-uv for running the environments, ruff for linting, pytest with coverage and the responses library for mocking HTTP calls, and pyright for type checking in standard mode with a note that not all dependencies carry type hints.

The release history explains the version number. The latest release is 5.0.0, published in April 2026, and before it are two alpha builds of the same version, 5.0.0a6 in December 2025 and 5.0.0a7 in February 2026. The last push was on 2026-10-14 with the repository not archived, so the work continues after the release.

The repository layout is small and modern: a source directory, tests, documentation, an agent instructions file and a context file, plus a copier answers file, which suggests the project skeleton is generated from a template and the maintainers fill in the answers.

The overall picture is a mature project structure wrapped around a service relationship that the maintainers do not control, and the readme is unusually straight about that. The extension is Apache 2.0 licensed, the documentation site is separate, and the authentication documentation has its own page for storage options and troubleshooting.

## Conclusion

mopidy-spotify suits someone who already runs Mopidy and keeps their library in Spotify, because it is the shortest path to Spotify in a Mopidy playlist or on a network player. It is a poor fit if you are on the free tier, if you need seeking or gapless playback, or if you are unwilling to re-authenticate every six months, because Spotify now expires refresh tokens. Before you install, read the three warnings at the top of the readme, check that the GStreamer Spotify plugin is present and checkable, and decide how you will store the credentials, since the keyring is preferred and a plaintext file is the fallback.

## FAQ

### How do I install mopidy-spotify?

With sudo python3 -m pip install --break-system-packages mopidy-spotify. You also need a Spotify Premium subscription, Mopidy 4.0 or later, and the GStreamer Spotify plugin for playback, which is not yet available from the Mopidy apt repository and must be built from source or installed from Debian packages for some platforms.

### How do I authorise mopidy-spotify to access my Spotify library?

Run mopidy spotify auth web, open the displayed URL, approve access in Spotify, and paste the result back into the terminal. If Mopidy runs as a system service, run sudo mopidyctl spotify auth web instead, and run the command as the same operating system user that runs Mopidy.

### What features does mopidy-spotify not support?

Seeking, gapless playback, volume normalization, saving items to My Music, podcasts, radio and Spotify Connect. Saving to My Music and podcasts are noted as possible through the web API. What does work is playback, search, read-only playlists, the top lists and Your Music in read-only mode, and lookup by URI.

### How often will I have to re-authenticate mopidy-spotify?

Every six months in practice, because Spotify has introduced refresh token expiration. The readme also warns that Spotify disabled streaming via third-party access tokens, that the workaround is a credentials file obtained with librespot, and that any manually created credentials file should be removed.

## Sources

- [License: Apache-2.0](https://github.com/mopidy/mopidy-spotify/blob/main/LICENSE)
- [mopidy/mopidy-spotify on GitHub](https://github.com/mopidy/mopidy-spotify)
- [Project website](https://mopidy.com/ext/spotify/)
- [README](https://github.com/mopidy/mopidy-spotify/blob/main/README.md)
- [Releases](https://github.com/mopidy/mopidy-spotify/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/mopidy-mopidy-spotify
