# How Provider Requirements Are Resolved and Installed in Music Assistant Server

> Discover how Music Assistant resolves provider requirements by validating and installing missing libraries automatically using UV's pip installer for seamless integration.

- Repository: [Music Assistant/server](https://github.com/music-assistant/server)
- Tags: internals
- Published: 2026-06-13

---

**Music Assistant resolves provider requirements by reading each provider's [`manifest.json`](https://github.com/music-assistant/server/blob/main/manifest.json), validating installed packages against declared dependencies in `load_provider_module`, and automatically installing missing libraries using UV's pip installer before importing the provider module.**

Music Assistant treats music providers as self-contained plugins with their own Python dependencies. Understanding how provider requirements are resolved and installed is essential for developers extending the platform or troubleshooting dependency conflicts. The server uses a dynamic runtime resolution system that checks manifests and installs packages on-demand rather than bundling all dependencies upfront.

## How Provider Requirements Are Declared

Each provider in the Music Assistant server declares its third-party dependencies in a [`manifest.json`](https://github.com/music-assistant/server/blob/main/manifest.json) file located in the provider's directory.

### The manifest.json Structure

The `requirements` key contains a list of pip-compatible package strings, typically pinned to specific versions:

```json
{
  "domain": "ytmusic",
  "name": "YouTube Music",
  "requirements": [
    "ytmusicapi==1.4.0",
    "google-auth==2.26.2"
  ]
}

```

According to the source code, when the core system initializes a provider, it reads this manifest from `music_assistant/providers/<domain>/manifest.json` before attempting to load the Python module.

## Runtime Resolution Pipeline

The resolution process occurs in four distinct phases orchestrated by the `load_provider_module` function in [`music_assistant/helpers/util.py`](https://github.com/music-assistant/server/blob/main/music_assistant/helpers/util.py).

### Step 1: Manifest Loading

When a provider is requested, `MusicAssistant` (defined in [`music_assistant/mass.py`](https://github.com/music-assistant/server/blob/main/music_assistant/mass.py)) retrieves the provider's manifest and extracts the `requirements` list. This list is passed as the second argument to `load_provider_module` along with the provider's domain identifier.

### Step 2: Dependency Validation

The `load_provider_module` function iterates over each requirement and verifies installation using `importlib.metadata`:

```python

# music_assistant/helpers/util.py

import importlib.metadata as metadata

async def load_provider_module(domain: str, requirements: list[str]) -> ModuleType:
    for req in requirements:
        pkg_name = req.split("==")[0]
        try:
            installed_version = metadata.version(pkg_name)
            if installed_version != req.split("==")[1]:
                raise metadata.PackageNotFoundError
        except metadata.PackageNotFoundError:
            # Installation triggered here

            pass

```

If the package is missing or the version mismatches, the function proceeds to installation.

### Step 3: UV Installation

For missing or outdated packages, Music Assistant invokes **UV** (an extremely fast Python package installer) via subprocess:

```python
cmd = [sys.executable, "-m", "uv", "pip", "install", req]
await subprocess.run(cmd, check=True)

```

This approach ensures deterministic, fast installations without requiring pre-bundled wheels or manual pip commands from the user.

### Step 4: Module Import

Once all requirements are satisfied, the provider module is imported dynamically:

```python
return importlib.import_module(f"music_assistant.providers.{domain}")

```

The fully initialized module is returned to the caller in [`music_assistant/mass.py`](https://github.com/music-assistant/server/blob/main/music_assistant/mass.py), which then instantiates the provider's main class.

## Complete Implementation Example

The following pattern demonstrates how the core system loads a provider with automatic dependency resolution:

```python
from music_assistant.helpers.util import load_provider_module

async def initialize_provider(domain: str, manifest: dict):
    # Extract requirements from the provider manifest

    requirements = manifest.get("requirements", [])
    
    # Resolve and install dependencies, then import module

    provider_mod = await load_provider_module(domain, requirements)
    
    # Instantiate the provider class

    return provider_mod.Provider()

```

## Bulk Dependency Management

For deployment scenarios requiring all provider dependencies upfront, the repository includes [`scripts/gen_requirements_all.py`](https://github.com/music-assistant/server/blob/main/scripts/gen_requirements_all.py). This script scans every provider's [`manifest.json`](https://github.com/music-assistant/server/blob/main/manifest.json), aggregates the `requirements` arrays, and writes a consolidated [`requirements_all.txt`](https://github.com/music-assistant/server/blob/main/requirements_all.txt) file:

```bash

# Generate consolidated requirements file

python scripts/gen_requirements_all.py

# Install all provider dependencies at once

uv pip install -r requirements_all.txt

```

Additionally, [`scripts/parse_manifest_deps.py`](https://github.com/music-assistant/server/blob/main/scripts/parse_manifest_deps.py) assists with CI diff-checking to ensure manifest requirements remain synchronized with the codebase.

## Summary

- **Declaration**: Provider requirements are declared in [`manifest.json`](https://github.com/music-assistant/server/blob/main/manifest.json) under the `requirements` key as pinned pip packages.
- **Resolution**: The `load_provider_module` function in [`music_assistant/helpers/util.py`](https://github.com/music-assistant/server/blob/main/music_assistant/helpers/util.py) handles runtime validation using `importlib.metadata`.
- **Installation**: Missing packages are installed using UV (`uv pip install`) via subprocess calls to ensure speed and reliability.
- **Integration**: The resolution pipeline is triggered by `MusicAssistant` in [`music_assistant/mass.py`](https://github.com/music-assistant/server/blob/main/music_assistant/mass.py) during provider initialization.
- **Bulk Operations**: Use [`scripts/gen_requirements_all.py`](https://github.com/music-assistant/server/blob/main/scripts/gen_requirements_all.py) to generate a unified requirements file for all providers.

## Frequently Asked Questions

### What happens if a provider requirement conflicts with core dependencies?

Music Assistant resolves provider requirements in isolation using UV, which respects the project's Python environment constraints. If a version conflict occurs between a provider's pinned requirement and the core system's dependencies, UV will raise a resolution error during the `pip install` phase, preventing the provider from loading until the conflict is manually resolved in the manifest.

### Can providers specify optional or conditional requirements?

According to the source code analysis, the current implementation requires all entries in the [`manifest.json`](https://github.com/music-assistant/server/blob/main/manifest.json) `requirements` array to be installed before the provider module imports. There is no built-in support for optional requirements; all listed packages are treated as mandatory and validated during the `load_provider_module` execution.

### How does Music Assistant handle installation failures?

If the `subprocess.run` call to `uv pip install` returns a non-zero exit code (for example, when a package is unavailable or network access is restricted), the `check=True` parameter raises a `CalledProcessError`. This exception propagates up to the caller in [`music_assistant/mass.py`](https://github.com/music-assistant/server/blob/main/music_assistant/mass.py), causing the provider initialization to fail gracefully with the error logged for diagnostic purposes.

### Where are the installed provider packages stored?

Packages installed by UV are placed in the same Python environment running the Music Assistant server process. Since UV operates within the active virtual environment or system Python (depending on deployment), provider dependencies coexist with core dependencies in `sys.path`, managed by the standard site-packages directory structure.