Skip to main content
Glama
nurasik14

lastfm-taste-mcp

by nurasik14

lastfm-taste-mcp

A read-only MCP server that lets an AI agent look at your Last.fm listening history: what you played this week, your most-played songs, what you loved, and what other music sounds like it.

The idea: you ask your agent something like "play something like what I've been into lately, but nothing I've heard before". The agent uses these tools to check your taste on Last.fm, picks the music, and then plays it using whatever music tool it has (Spotify, for example). This server only reads data. It doesn't play anything and can't change your Last.fm account.

Spotify / any player --scrobbles--> Last.fm
Agent --MCP (stdio)--> lastfm-taste-mcp --HTTPS + API key--> Last.fm API
Agent --its own music tool--> plays the pick

What you can ask

  • "What were my top songs this week?"

  • "Have I listened to more Radiohead this month than last month?"

  • "Play something similar to my favourite track, but not something I've already played."

  • "I want something chill. What do I already like that fits, and what's new?"

  • "What genre is this artist?"

The agent decides which tools to call. Each tool returns a short plain-text answer (not raw Last.fm JSON), so a few calls don't fill up the agent's context.

Related MCP server: Claud-Ear

Requirements

  • Python 3.11 or newer and uv

  • A Last.fm account that is collecting your plays (scrobbling)

  • A Last.fm API key (free)

Setup

1. Make sure Last.fm is recording your plays

For Spotify: on last.fm go to Settings → Applications and connect Spotify Scrobbling. Last.fm only sees plays from the moment you connect, so a new account starts empty.

The Spotify connection expires every 6 months. When it does, scrobbling stops without any warning, and the data goes stale. The Applications page shows how many days are left. To renew it, click Disconnect and then Connect.

2. Get an API key

Create an API account at https://www.last.fm/api/account/create. The app name can be anything, and you can leave the callback URL empty. You only need the API key. This server never uses the shared secret.

3. Store the key in an env file

The server reads two environment variables:

Variable

Required

Meaning

LASTFM_API_KEY

yes

Your Last.fm API key

LASTFM_USERNAME

no

Default user for the user_* tools, used when the agent doesn't name one

The username is the one in your profile URL (last.fm/user/<name>). It can differ from the Spotify name shown on Last.fm's settings page.

git clone https://github.com/nurasik14/lastfm-taste-mcp
cd lastfm-taste-mcp
(umask 077; printf 'LASTFM_API_KEY=%s\nLASTFM_USERNAME=%s\n' 'your-api-key' 'your-lastfm-name' > .env)

.env is in .gitignore. The umask 077 makes the file readable only by you.

4. Register it with your MCP client

Hermes Agent:

hermes mcp add lastfm --command uv --args run --directory "$PWD" --env-file "$PWD/.env" lastfm-taste-mcp
hermes mcp test lastfm

--args must come last. Start a new Hermes session afterwards so the tools load. Hermes gives stdio servers only a filtered environment, so pass the key through --env-file (as above) or --env. Exporting it in your shell isn't enough.

Other MCP clients (Claude Desktop, Cursor, and others) use a JSON entry like this:

{
  "mcpServers": {
    "lastfm": {
      "command": "uv",
      "args": ["run", "--directory", "/path/to/lastfm-taste-mcp", "--env-file", "/path/to/lastfm-taste-mcp/.env", "lastfm-taste-mcp"]
    }
  }
}

Without cloning, uv can run it straight from GitHub. Your client then has to pass the variables in an env block:

{
  "mcpServers": {
    "lastfm": {
      "command": "uvx",
      "args": ["--from", "git+https://github.com/nurasik14/lastfm-taste-mcp", "lastfm-taste-mcp"],
      "env": { "LASTFM_API_KEY": "your-api-key", "LASTFM_USERNAME": "your-lastfm-name" }
    }
  }
}

The server starts and lists its tools even without a key. Tool calls then return "LASTFM_API_KEY is not set". If you see that after adding the key, restart the client: a server that was already running won't re-read the file.

Tools

All 24 tools are read-only and marked with MCP's readOnlyHint. Most take limit (default 10–20, max 200), and the list-style ones also take page.

Your listening. Every one takes an optional user and falls back to LASTFM_USERNAME.

Tool

What it returns

user_get_info

Total scrobbles, artist/track/album counts, country, signup date

user_get_recent_tracks

Individual plays with timestamps, newest first; since / until take ISO dates

user_get_top_tracks

Most-played tracks for period = 7day, 1month, 3month, 6month, 12month, overall

user_get_top_artists

Most-played artists for a period

user_get_top_albums

Most-played albums for a period

user_get_loved_tracks

Tracks you hearted, with the date

user_get_weekly_chart_list

Past weeks that have charts, with their from / to values

user_get_weekly_track_chart

Track chart for one week (latest by default)

user_get_weekly_artist_chart

Artist chart for one week

user_get_weekly_album_chart

Album chart for one week

user_get_top_tags

Tags you applied on Last.fm (not the genre of your music)

user_get_personal_tags

Items you tagged with a given tag

user_get_friends

Your Last.fm friends

What music sounds like.

Tool

What it returns

track_get_top_tags

Genre/mood tags listeners gave a track

artist_get_top_tags

Tags for an artist (use it when a single track has none)

album_get_top_tags

Tags for an album

track_get_info

Album, length, global popularity, tags, and your play count and loved status for that track

Finding music.

Tool

What it returns

track_get_similar

Similar tracks with a 0–1 match score

artist_get_similar

Similar artists with a 0–1 match score

artist_get_top_tracks

An artist's most popular tracks across all listeners

tag_get_top_tracks

Most popular tracks with a tag (e.g. chill, shoegaze)

tag_get_top_artists

Most popular artists with a tag

tag_get_info

What a tag means and how widely it's used

tag_get_similar

Related tags

Things to know

  • Similar-track data is patchy. track_get_similar often returns nothing for remixes, covers, and lesser-known tracks. artist_get_similar plus artist_get_top_tracks usually works as a fallback. tag_get_similar is often empty as well.

  • Only finished listens count. Last.fm scrobbles a track once it has played for half its length or 4 minutes, so skipped songs never show up.

  • Results are artist + title, not Spotify links. To play a pick, the agent has to look the song up in its music tool first.

  • Errors come back as readable text for the agent: a misspelled name or unknown user (Last.fm error 6), a private profile (17), a rate limit (29), or a bad key (10).

  • Rate limits. Last.fm limits how many requests each IP can make and asks clients not to make excessive calls. Every tool call is one API request.

Privacy and security

  • Read-only. The server has no Last.fm login, so it can't scrobble, love tracks, or edit your profile.

  • The API key is only read from the environment, never from the code. It travels in request URLs (that's how the Last.fm API works), so the server silences httpx's request logging. That log would otherwise write the key into your MCP client's log files.

  • Last.fm listening data is public by default: anyone with an API key can read it. If you turn on "Hide recent listening information" in your Last.fm privacy settings, some user_* calls may be refused (error 17).

Development

uv sync                 # create .venv with the runtime and dev dependencies
uv run pytest -q        # 25 tests; they use a fake Last.fm, so no network or key is needed
uv run lastfm-taste-mcp # run the server by hand (it speaks JSON-RPC on stdin/stdout)
src/lastfm_taste_mcp/
  client.py    Last.fm HTTP client, error translation, helpers for Last.fm's JSON quirks
  server.py    the 24 MCP tools (plain async functions registered with @server.tool)
  __init__.py  main(): start the server on stdio
tests/
  conftest.py          FakeLastfm, built on httpx.MockTransport
  test_client.py       request shape, errors, JSON quirks
  test_server.py       tool list, reply trimming and errors, via an in-process MCP client
  test_stdio_smoke.py  starts the real server over stdio, the way a client does

Built with the official MCP Python SDK (v2) and httpx. Data comes from the Last.fm API. This project isn't affiliated with Last.fm.

License

MIT

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    A
    maintenance
    A Model Context Protocol (MCP) server for Last.fm. Gives AI assistants access to your listening history, music discovery, and detailed track/artist/album information.
    230 npm
    52
    MIT
  • A
    license
    A
    quality
    C
    maintenance
    An MCP server for the Last.fm API that enables LLM agents to access music data including user profiles, listening history, top charts, search, and artist/album/track metadata.
    16
    MIT
  • A
    license
    Not graded
    quality
    A
    maintenance
    An MCP server for the Last.fm API, exposing artist, album, track, chart, and user data as read-only tools. Supports optional writes, auth, and experimental methods over stdio or HTTP.
    MIT