MCP server for music recognition: identify any song, then get its BPM, key and Camelot code.
355

Identify any song, then get its BPM, musical key and harmonically compatible tracks — from inside Claude, Cursor, or any MCP client.
English · 简体中文 · 日本語 · 한국어 · Español · Deutsch · Français
An MCP server for music recognition and audio analysis, backed by Song Finder — a free online song finder that identifies music from a file, a microphone recording, or a link.
Ask your assistant "what song is playing in this YouTube video?" and it answers. Then ask "what's the BPM and key?" and "find me something that mixes into it" — and it chains straight through.
| Tool | What you get |
|---|---|
identify_song | Song title, artist, album, label, release date and Spotify / Apple Music links — from a URL or a local audio file |
search_tracks | Catalogue lookup by title/artist, returning ISRC codes |
get_track_analysis | Tempo (BPM), musical key, Camelot code, harmonically compatible keys, energy, danceability, valence, acousticness, loudness |
find_similar_tracks | Similar tracks — optionally restricted to harmonically compatible keys for DJ sets |
identify_song accepts links from YouTube, TikTok, Instagram, SoundCloud, Bilibili and X, plus any direct audio or video URL. Local files can be mp3, m4a, wav, flac, ogg, opus, aac or webm.
No API key. No account. No rate card.
claude mcp add songfinder -- npx -y songfinder-mcp
Add to claude_desktop_config.json:
{
"mcpServers": {
"songfinder": {
"command": "npx",
"args": ["-y", "songfinder-mcp"]
}
}
}
Same shape — command: npx, args: ["-y", "songfinder-mcp"].
Requires Node.js 20 or newer.
No Node.js on the host, and the server runs sandboxed — worth having, since an MCP server otherwise executes with whatever your agent can reach.
{
"mcpServers": {
"songfinder": {
"command": "docker",
"args": ["run", "-i", "--rm", "lenfenn/songfinder-mcp"]
}
}
}
Also on GitHub Container Registry as ghcr.io/songfinder-dev/songfinder-mcp — same image, same digests.
-i is not optional: the server speaks JSON-RPC over stdin and stdout, with no port and no HTTP.
To identify local files, mount the directory holding them. Inside a container, file_path refers to the container's filesystem, so a host path the container cannot see comes back as "no readable file":
{
"command": "docker",
"args": ["run", "-i", "--rm", "-v", "/Users/you/Music:/audio:ro", "ghcr.io/songfinder-dev/songfinder-mcp"]
}
Then ask for /audio/track.mp3 rather than the host path. :ro keeps it read-only — the server only ever reads.
Images are built for amd64 and arm64 natively, so Apple Silicon runs without emulation.
You: What song is playing in this video? (pastes a YouTube link)
Assistant (calls
identify_song) Blinding Lights Match confidence: 100% · ISRC: USUG11904206
You: Is it fast? What key?
Assistant (calls
get_track_analysis) Blinding Lights — The Weeknd · Album: After Hours · Released: 2020 Tempo: 171 BPM · Key: C#/Db Major (Camelot 3B, Open Key 8d) Mixes with: 3A, 2B, 4B Energy 73% · Danceability 51% · Valence 33% · Loudness −6.0 dB
You: Give me three tracks that mix into it.
Assistant (calls
find_similar_trackswithharmonic: true) …
(Those analysis figures are the real output, not a mock-up.)
Two tracks in adjacent Camelot positions share enough harmonic content to be layered without clashing. 3B mixes cleanly into 3A, 2B and 4B — which is exactly what find_similar_tracks filters on when you pass harmonic: true.
The analysis also cross-checks tempo against a second provider. When the two disagree by more than ~3 BPM, the output says so — that gap almost always means one source read the track at half- or double-time, which matters enormously if you are beatmatching.
Recognition costs real quota, so the endpoint rate-limits per IP. If you fire several identify_song calls back to back you will see a "rate limited" message; wait a few seconds.
Not everything is identifiable. Live versions, unreleased edits, heavily-processed remixes and instrumental beds frequently have no catalogue entry. When a clip lands on an intro or a silent gap, pass start_seconds to sample further in.
The credited artist is whichever catalogue entry matched. Widely re-uploaded tracks often match a white-label or re-upload record rather than the original release, so a famous song can come back credited to a label nobody has heard of. The title is still correct — search_tracks on that title surfaces the original, and the tool output says as much when it happens.
Local files are uploaded to songfinder.dev for identification and are not retained. Keep excerpts under 10MB — a 10–20 second clip is plenty and identifies faster than a full track.
Acoustic coverage is uneven. Long-tail and regional releases often have a tempo but no genre, or no analysis at all. Missing fields are omitted rather than reported as null.
| Variable | Default | Purpose |
|---|---|---|
SONGFINDER_API_URL | https://songfinder.dev | Point at a different deployment |
pnpm install
pnpm build
node test/smoke.mjs # real JSON-RPC handshake against the live API
pnpm inspect # MCP Inspector
The smoke test is deliberately unmocked. The failure worth catching — a renamed field or a tightened origin check upstream — is invisible to a mocked test and is the one that actually happens.
get_track_analysisfind_similar_tracksMIT
Content type
Image
Digest
sha256:e1d67b414…
Size
57.7 MB
Last updated
about 1 month ago
docker pull lenfenn/songfinder-mcp