music-mcp-agent
README.md
# Music AI Agent — MCP Server - specialized in classical music recognition
A Python MCP server exposing music analysis tools: catalog search, track
metadata, local tempo/key/energy detection, recommendations, and optional
song recognition.
## Why it's built this way
Spotify locked down its `audio-features`, `audio-analysis`, `recommendations`,
and `related-artists` endpoints for all new apps in November 2024, and hasn't
reopened them. So:
- **Search + track metadata** → still Spotify (works great).
- **Tempo / key / energy** → computed locally with `librosa` on an actual
audio file, instead of asking Spotify for numbers it no longer gives out.
- **Recommendations** → Last.fm's `track.getSimilar`, which is still free
and public.
- **"What song is this?"** → a separate problem (audio fingerprinting), done
via AudD's API — optional, only needed if you want that specific feature.
## Setup
```bash
cd music-mcp-agent
python -m venv venv
source venv/bin/activate # Windows: venv\Scripts\activate
pip install -r requirements.txt
cp .env.example .env
```
Fill in `.env`:
- `SPOTIFY_CLIENT_ID` / `SPOTIFY_CLIENT_SECRET` — required for search & metadata.
Create an app at https://developer.spotify.com/dashboard (takes ~2 minutes,
no approval wait — client-credentials apps don't need extended access).
- `LASTFM_API_KEY` — required for `get_similar_tracks`. Free, instant:
https://www.last.fm/api/account/create
- `AUDD_API_KEY` — optional, only for `identify_song`. Free tier at https://audd.io/
## Run it
```bash
python server.py
```
## Connect it to Claude Desktop
Add to your Claude Desktop config (`claude_desktop_config.json`):
```json
{
"mcpServers": {
"music-agent": {
"command": "/absolute/path/to/venv/bin/python",
"args": ["/absolute/path/to/music-mcp-agent/server.py"]
}
}
}
```
Restart Claude Desktop. The tools will show up under the 🔌 icon.
## Tools
| Tool | Input | What it does |
|---|---|---|
| `search_music` | `query`, `limit` | Search Spotify catalog |
| `get_track_info` | `track_id` | Full metadata for a track |
| `analyze_audio_file` | `file_path` (local) | Tempo, key, energy — no API |
| `get_similar_tracks` | `artist`, `track`, `limit` | Recommendations via Last.fm |
| `identify_song` | `file_path` (local clip) | Fingerprint recognition via AudD |
| `resolve_classical_work` | `query` (raw title/artist string) | Extracts composer, work, performers via MusicBrainz |
| `find_live_performances` | `query` (work/composer/orchestra), `city` | Upcoming concerts via Songkick |
### Classical music: why two extra steps
Spotify and Last.fm treat a classical recording as one flat string —
`"Symphony No. 5 in C Minor, Op. 67: I. Allegro con brio"` — with composer,
work, and performing orchestra mashed together inconsistently. Neither is a
good source for "what's this piece" or "who's performing it live," so:
1. `resolve_classical_work` uses **MusicBrainz** (free, no key needed beyond
a descriptive User-Agent) to split that string into composer + canonical
work title.
2. `find_live_performances` takes that composer/work/orchestra and searches
**Songkick's** events database for upcoming concerts, optionally filtered
by city.
Typical flow: `search_music` → `resolve_classical_work` on the result →
`find_live_performances` with the resolved composer or orchestra name.
**Songkick access isn't instant** — you have to apply at
https://www.songkick.com/developer and approval is manual (can take a
couple of weeks), so plan for that lead time before you rely on
`find_live_performances`.
**Note on Bachtrack**: it's the most classical-specific concert listings
site, but it has no public developer API — only a searchable website — so
it isn't wired in here.
## Next steps to extend this
- Add caching (the Spotify token, repeated searches, MusicBrainz lookups)
with something like `diskcache` — MusicBrainz in particular rate-limits
to ~1 request/second per the terms of their free API.
- Add a `create_playlist` tool if you get user-auth (Authorization Code flow)
working instead of client-credentials — needed for anything that writes to
a user's account.
- Swap `analyze_audio_file` to batch-process a folder for a full library scan.
- If AudD's free tier is too limited, ACRCloud is the other common choice for
fingerprinting, similar integration shape.
- Once Songkick access comes through, consider adding a `subscribe_orchestra`
tool that periodically checks an orchestra's calendar and only surfaces new
additions — more useful than re-querying the full calendar each time.
Structure:
music-mcp-agent/
├── config.py # loads all env vars, once
├── server.py # MCP registration only
├── clients/
│ ├── __init__.py # marks clients/ as a Python package
│ ├── spotify.py # search + track info
│ ├── audio_analysis.py # local librosa tempo/key/energy
│ ├── lastfm.py # similar tracks
│ ├── audd.py # song recognition
│ ├── musicbrainz.py # classical work resolution
│ └── songkick.py # live performances
├── requirements.txt
├── .env.example
└── README.md
This server cannot be deployed
Maintenance
ActivityStale
ResponsivenessNo issues