How to Implement ProviderFeature Flags in a New Music Assistant Provider

Music Assistant providers declare capabilities through the ProviderFeature enum by listing supported flags in manifest.json, accepting a supported_features set in the constructor, and guarding optional methods with runtime checks against this set.

The music-assistant/server repository uses feature flags to determine which providers support specific operations like browsing, searching, or library synchronization. When creating a new provider, you must implement ProviderFeature flags to advertise capabilities to the core system, ensuring the Music Assistant only invokes your code for operations you actually support.

Understand the ProviderFeature Enum

The ProviderFeature enum is defined in the separate music-assistant/models repository within music_assistant_models/enums.py. It declares granular capabilities such as BROWSE, SEARCH, LIBRARY_TRACKS, LIBRARY_ALBUMS, and ARTIST_TOPTRACKS. Each flag represents a contract—if your provider includes a flag in its supported set, the core expects the corresponding method to be implemented. Import the enum in your provider code:

from music_assistant_models.enums import ProviderFeature

Declare Feature Support in the Manifest

Every provider must include a manifest.json file that serves as the canonical capability declaration. The core loads this manifest at startup via music_assistant/helpers/util.py → load_manifest() and converts the array into a frozenset[ProviderFeature] passed to your constructor.

Example from music_assistant/providers/zvuk_music/manifest.json:

{
  "type": "music",
  "name": "ZVuk",
  "supported_features": [
    "BROWSE",
    "SEARCH",
    "LIBRARY_TRACKS",
    "LIBRARY_ALBUMS",
    "LIBRARY_ARTISTS",
    "ARTIST_ALBUMS",
    "ARTIST_TOPTRACKS"
  ]
}

The values must match the ProviderFeature member names exactly. Case sensitivity matters—browse will not match BROWSE.

Accept the Feature Set in the Provider Class

When the core instantiates your provider, it passes the populated feature set as the supported_features parameter. The base class Provider in music_assistant/models/provider.py stores this in self._supported_features.

Example implementation in music_assistant/providers/zvuk_music/provider.py:

class ZVukMusicProvider(Provider):
    def __init__(self, mass, manifest, config, supported_features):
        # Base class stores the set in self._supported_features

        super().__init__(mass, manifest, config, supported_features)
        # Keep a direct reference for convenience in method guards

        self.supported_features = supported_features

Guard Optional Functionality with Runtime Checks

Any method implementing an optional capability must verify the flag exists before executing. This pattern appears throughout existing providers like Spotify and YouTube Music.

Example guard implementation:

async def get_browse_items(self, **kwargs):
    """Return browse items only if the provider advertises BROWSE support."""
    if ProviderFeature.BROWSE not in self.supported_features:
        raise NotImplementedError("Browse not supported")
    # ... actual browse logic ...

Apply this check to all optional methods to prevent crashes when the core queries capabilities.

Complete Implementation Example

Below is a skeleton showing how to integrate ProviderFeature flags into a new provider:


# music_assistant/providers/my_provider/provider.py

from music_assistant_models.enums import ProviderFeature
from music_assistant.models.provider import Provider

class MyProvider(Provider):
    def __init__(self, mass, manifest, config, supported_features):
        super().__init__(mass, manifest, config, supported_features)
        self.supported_features = supported_features
    
    async def search(self, query: str, media_types: list, limit: int = 10):
        if ProviderFeature.SEARCH not in self.supported_features:
            return []
        # ... search implementation ...

    
    async def get_library_tracks(self):
        if ProviderFeature.LIBRARY_TRACKS not in self.supported_features:
            raise NotImplementedError("Library tracks not supported")
        # ... track retrieval logic ...

Corresponding manifest.json:

{
  "type": "music",
  "name": "My Provider",
  "supported_features": [
    "SEARCH",
    "LIBRARY_TRACKS"
  ]
}

Test Feature Discovery

The core discovers providers via music_assistant/models/provider.py → load_providers(). To verify your flags work correctly, write unit tests that instantiate your provider with specific flags and assert inclusion in MusicAssistant.get_providers_supporting_feature(). Reference the existing test patterns in tests/test_cross_type_features.py for the standard verification approach.

Summary

  • Import ProviderFeature from music_assistant_models.enums to access capability constants.
  • Declare supported features in your provider's manifest.json using exact enum member names.
  • Accept the supported_features set in your provider's __init__ and forward it to the base Provider class.
  • Guard every optional method with if ProviderFeature.FLAG not in self.supported_features: to prevent invalid calls.
  • Reference existing providers in music_assistant/providers/ (such as ZVuk Music, Spotify, or YouTube Music) for canonical implementation patterns.

Frequently Asked Questions

What happens if I omit a feature flag from my provider's manifest?

If you omit a flag from manifest.json, the core will not include that capability in the supported_features set passed to your constructor. Consequently, the Music Assistant UI will disable related functionality, and core methods like get_providers_supporting_feature() will exclude your provider from those operations, even if you implement the corresponding methods.

Can I dynamically change ProviderFeature flags at runtime?

No. The supported_features set is populated once at provider initialization from the manifest and stored as a frozen set in the base class. To change capabilities, you must update manifest.json and restart the Music Assistant server so the core reloads the provider configuration via load_manifest().

Where is the ProviderFeature enum defined?

The enum is defined in the music-assistant/models repository, specifically in music_assistant_models/enums.py. This is a separate package from the main server. Import it using from music_assistant_models.enums import ProviderFeature to ensure compatibility with the core's type checking.

Do I need to implement all methods for a feature flag I declare?

Yes. If you declare a flag like BROWSE or SEARCH in your manifest, the core expects the corresponding methods (such as get_browse_items() or search()) to be available and functional. While you should guard these methods with runtime checks against self.supported_features, declaring a feature without implementing its interface will raise NotImplementedError or similar exceptions when the core attempts to use those capabilities.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →