MCP server for Music Assistant with high-level, LLM-friendly tools for controlling a home audio system
Music Assistant MCP demonstrates solid tool design with clear verb-based naming, comprehensive parameter descriptions, and well-structured schemas. All 11 tools have descriptions (avg 156 chars) and input schemas with typed parameters. However, output schemas are not documented in the source, parameter descriptions lack explicit format/range constraints in several tools, and error handling guidance is minimal. The server follows good composition patterns (single responsibility per tool, chainable IDs) and accepts human-friendly identifiers (player/source names) alongside defaults. Naming is consistent and action-oriented (play, control, queue, transfer). Main gaps: no documented return types, missing enum constraints for some parameters, and no recovery guidance in error scenarios.
Browse the provider library hierarchically. Omit `path` to list root providers, e.g. path=None -> "spotify://library" -> "spotify://library/playlists".
Playback control - play, pause, stop, skip, seek, etc.
Group or ungroup players (e.g. syncing a LedFX visualizer player, or any speaker group).
List every Music Assistant player with id, name, power state and volume. Most other tools resolve the player themselves (by name, or the configured default) - only call this if the user explicitly asks what players exist, or a player name didn't match anything and you need to show what's available.
List configured music providers (Spotify, Tidal, local/SMB/WebDAV shares, ...) with whether each is a streaming ("online") or local file ("offline") provider. Only call this if the user asks what sources/providers are configured, or a `source`/`scope` value passed to `play`/`search` didn't match anything.
Output schemas not documented. No tool returns a documented schema showing what fields the LLM should expect (e.g., play returns what? queue state? current track?). This forces LLMs to guess downstream field names and risks broken tool chains.
Missing enum constraints for string parameters. 'command' in control (play|pause|stop|toggle|next|previous|seek), 'action' in group (join|leave), 'option' in play/play_random (play|replace|next|add), and 'repeat' in queue (off|one|all) accept free-form strings instead of enums. LLMs will hallucinate invalid values.
No error recovery guidance. Tool descriptions do not explain what to do if a player name doesn't match, a source isn't found, or a command fails. Error messages should guide the LLM to call list_players or list_providers, but this is not documented.
Inferred effective spec: <=2025-11-25.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | C | 64 | <=2025-11-25 | v2 |
Search for media and play it on a player - one call, no separate search step.
Build and play a random mix pulled straight from the library - no search query needed. Use for "play something"/"surprise me"/"random mix from my local files" type requests.
Queue inspection and management for one player's queue.
Raw search, returned without playing anything - use `play` instead unless the user just wants to know what's available. media_types defaults to ["playlist"].
Move what's currently playing on `source_player` over to `target_player`.
Set volume. Provide one of level (0-100), adjust ("up"/"down"), mute (true/false). If none of level/adjust/mute are given, just reports the current level instead of erroring - useful if the caller only wanted to check volume.
Parameter format constraints not explicit. 'player' and 'source' accept 'name/substring' but no length limits or character restrictions stated. 'count' in play_random accepts 1-100 but not documented in description. 'position_seconds' in control has no range stated.
Pagination not addressed. search() returns 'limit' (default 15) but no 'offset', 'page', or 'next_cursor' parameter for large result sets. If a user searches for 'rock' and gets 15 results, there's no way to fetch the next 15.