Skip to main content
Glama

navidrome-mcp

An MCP server for Navidrome that builds playlists which actually match a described mood — grounded in what you own, what you have listened to, and how you yourself have labelled your music.

Why this exists

Navidrome's API alone cannot do this, for three concrete reasons:

  1. Its REST filtering is exact-match only. year=1997 works; year=1990-1999 silently returns nothing. There are no ranges and no AND/OR, so a query like "90s rock I haven't played in a year, max 2 per artist" is not expressible.

  2. It keeps no listen history. Only a playCount and a last playDate. There is no way to ask "what do I put on at 7am on a Tuesday".

  3. Nothing in the library says how a track feels. Measured on a real 9,311-track library: 32 genres with Rock alone covering 47%, BPM present on 24 tracks (0.3%), ReplayGain on 222 (2%), MusicBrainz recording IDs on 222 (2%). That last number also rules out AcousticBrainz as a primary mood source — its audio-derived mood models are keyed by MBID, and resolving the rest via ISRC → MusicBrainz (rate-limited to 1 req/s) would still only reach ~23% of the library.

So this server maintains its own index and joins three sources:

Source

Provides

Navidrome (native + Subsonic APIs)

Authoritative metadata, similarity agents, the playlist write path

ListenBrainz

Timestamped listen history — time-of-day and weekday habits

Last.fm

A real descriptive tag vocabulary (nu-disco, melancholy, shoegaze)

It also treats your existing curated playlists as your mood vocabulary. If you have playlists called golden hour, cranked and slow shreds, those words already mean something specific in your library — far more than a generic genre ever will.

Related MCP server: Navidrome-MCP

The mood pass

Those playlists cover maybe 40% of a library, so on their own they can only answer mood questions about tracks you already filed. A one-time enrichment pass closes that gap: every track gets energy, valence, intensity, acoustic-vs-electronic, free-form descriptors, the curated vibe it reads as, and the times of day it fits.

The inference is grounded in your own playlists — they're a hand-labelled training set in your own words — so unfiled tracks land in the same space as the ones you filed. Results are cached permanently, so this runs once and afterwards only picks up new music.

Cost stays small through three things: batching ~40 tracks per request, prompt-caching the large identical taxonomy prefix (the first batch runs alone, so the rest hit a warm cache instead of all missing it concurrently), and running with thinking disabled — this is classification, not reasoning. Set ANTHROPIC_API_KEY to enable it and MOOD_MODEL to trade quality for spend; without a key everything else still works and only the mood filters go dark.

Design notes

  • In-memory index, no database. A full library pull is ~20s for ~10k tracks; once local, every compound query is a single array pass. A JSON snapshot on disk makes restarts instant. Deliberately no native dependency, so it installs under npm ci --ignore-scripts on Node 20.

  • The index is a cache, never a source of truth. If the snapshot is missing or unreadable the server just re-syncs.

  • Navidrome's own compound engine is still exposed via create_smart_playlist, for standing playlists that should keep re-evaluating server-side. Note those rules can only see Navidrome's own fields — not ListenBrainz listens or Last.fm tags.

Tools

Tool

Purpose

describe_library

Orientation: size, genres, decades, curated vibes, tag vocabulary

search_tracks

The workhorse — full compound filtering, diversity caps, affinity ranking

get_vibe_profile

What one of your curated moods actually consists of

similar_tracks

Expand from seeds via agents + your own playlist co-occurrence

listening_history

recent / top / by_hour / by_weekday / rediscover / trending

list_playlists, get_playlist

Read playlists

create_playlist, update_playlist, delete_playlist

Write playlists

create_smart_playlist

Self-updating rules-based playlists

daylist_context

Everything needed to generate this hour's daylist

commit_daylist

Publish the rolling daylist atomically

refresh_index

Re-sync from Navidrome / ListenBrainz

Prompt: daylist — generates a Spotify-style daylist for the current hour.

Configuration

Env var

Required

Notes

NAVIDROME_URL

yes

e.g. http://host:4533

NAVIDROME_USERNAME / NAVIDROME_PASSWORD

yes

Playlists are created as this user

NAVIDROME_PROXY

no

socks5://host:port if Navidrome is only reachable via a proxy hop

LISTENBRAINZ_USER

no

Listen history is a public read; no token needed

LASTFM_API_KEY

no

Defaults to Navidrome's bundled public key

NAVIDROME_TZ

no

Default America/Chicago. Time-of-day analysis depends on this

NAVIDROME_DATA_DIR

no

Snapshot location. Default /data/navidrome-mcp

DAYLIST_PLAYLIST_NAME

no

Default daylist

NAVIDROME_ENRICH

no

0 disables background Last.fm tag fetching

Licence

MIT

Install Server
A
license - permissive license
A
quality
B
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

View all related MCP servers

Related MCP Connectors

  • Search MusicBrainz artists, releases, works, labels; resolve ISRC/ISWC/barcode; fetch cover art.

  • Spotify MCP — Web API via client_credentials OAuth

  • Recommendations, search, catalogue, analytics, and platform admin tools for NeuronSearchLab

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/312-dev/navidrome-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server