lastfm-mcp
Provides tools for accessing Last.fm listening history, including recent scrobbles, top artists/albums/tracks, artist history, and rediscovery candidates based on scrobbles.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@lastfm-mcpWhat are my top artists from the past month?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
lastfm-mcp
A small, open-source, read-only MCP server for Last.fm listening history. It is designed to support music discovery and rediscovery in MCP clients and can be packaged as a ChatGPT/Codex plugin.
What v0.3 does
recent scrobbles;
top artists, albums and tracks over Last.fm's standard periods;
check whether a listener has heard a named artist and roughly how much;
identify rediscovery candidates: historically important artists with little recent listening;
support multiple public Last.fm profiles without asking end users for API credentials;
run over stdio or Streamable HTTP;
include a portable plugin manifest, MCP configuration template, and music-discovery skill.
The server is read-only. It does not use Last.fm write APIs and does not require a Last.fm shared secret.
Related MCP server: lastfm-mcp
Requirements
Node.js 20 or newer
one Last.fm API key for the server/operator
Personal/local setup
Copy .env.example to .env and set:
LASTFM_API_KEY=your_real_api_key
LASTFM_USERNAME=WJMonde
LASTFM_USER_AGENT=lastfm-mcp/0.3.0LASTFM_USERNAME is optional in v0.3. Keeping it set gives personal/local use the same convenient behaviour as v0.2. If it is omitted, every tool call must include a username.
Install dependencies:
npm.cmd installTypecheck:
npm.cmd run typecheckRun locally over stdio
npm.cmd run devRun locally over HTTP
npm.cmd run dev:httpDefault endpoint:
http://127.0.0.1:3000/mcpFor a cloud/container host, the platform will often require:
HOST=0.0.0.0Terminate TLS at the hosting platform and expose a stable HTTPS /mcp URL for plugin use.
Tools
Each tool now accepts an optional username. If LASTFM_USERNAME is configured locally, it is used as the fallback.
recent_scrobbles
Returns recent scrobbles, optionally bounded by UNIX timestamps.
top_items
Returns top artist, album or track items for overall, 7day, 1month, 3month, 6month or 12month.
artist_history
Uses Last.fm's artist information endpoint with the requested username to report whether that listener has scrobbled an artist and the approximate play count.
rediscovery_candidates
Compares all-time top artists against a recent period and surfaces historically significant artists with little or no recent listening. The heuristic is deliberately explainable.
Plugin packaging
The repository includes:
plugin.json
mcp.json
skills/lastfm-music-discovery/SKILL.mdBefore using the package against a deployed server, replace the placeholder URL in mcp.json:
"url": "https://YOUR-PUBLIC-DOMAIN.example/mcp"with the real stable HTTPS MCP endpoint.
See docs/PUBLIC-PLUGIN-ROADMAP.md for the path from this prototype to public submission.
Build and test
npm.cmd run typecheck
npm.cmd run build
npm.cmd testSecurity and privacy
Never commit
.env.Keep the Last.fm API key server-side.
End users should provide only a public Last.fm username.
Do not request users' Last.fm password, shared secret, session key, or API key.
See
docs/PRIVACY.mdbefore deploying publicly.
Available Tools
4 toolsartist_historyARead-onlyIdempotent
Check whether a Last.fm user has listened to an artist and return the approximate total scrobble count. Pass a username unless the server has a local default.
| Name | Required | Description | Default |
|---|---|---|---|
| artist | Yes | Artist name. Last.fm autocorrection is enabled. | |
| username | No | Last.fm username. Optional only when the server has a local default configured. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, openWorldHint=true, and idempotentHint=true, indicating safe, non-destructive, and idempotent behavior. The description adds that the result is 'approximate' (not exact) and that a local default for username may exist, which are useful context not captured by annotations or schema. No contradiction.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, no filler. The main action and return value are front-loaded, and the username note is brief. Only minor improvement would be to explicitly state the tool name in the description for clarity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple read-only check with two parameters fully described in schema, the description covers the primary purpose and the only subtlety (username default). It does not specify what happens when the user has never listened (e.g., returns zero scrobbles or an error), but given no output schema and low complexity, this is a minor gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents both parameters. The description clarifies that username is optional only under a specific server condition, which adds a little beyond the schema. Baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States specific verb ('Check whether'), resource ('whether a Last.fm user has listened to an artist'), and the return value ('approximate total scrobble count'). It directly distinguishes from siblings like top_items or recent_scrobbles by focusing on a single artist check rather than lists.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides the core use case (checking if a user has listened to an artist) and notes that a username must be passed unless the server has a local default. However, it does not explicitly contrast with sibling tools (e.g., when to use recent_scrobbles instead), and gives no guidance on when not to use this tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
recent_scrobblesARead-onlyIdempotent
Get a Last.fm user’s most recent scrobbles. Read-only. Pass a username unless the server has a local default.
| Name | Required | Description | Default |
|---|---|---|---|
| to | No | Optional UNIX timestamp; only return scrobbles before this time. | |
| from | No | Optional UNIX timestamp; only return scrobbles after this time. | |
| limit | No | Number of scrobbles to return (1-200). | |
| username | No | Last.fm username. Optional only when the server has a local default configured. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and openWorldHint, so the description's 'Read-only' adds nothing beyond the structured data. It provides no additional behavioral context such as time-range boundaries, pagination behavior, or rate-limit considerations, and the local-default note already appears in the schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three short sentences, front-loading the primary purpose and staying scannable. The redundant read-only note is harmless, and no filler or vague phrasing is present.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read-only list tool with all parameters documented in the schema and safety covered by annotations, the description covers the essentials. It omits return-format details, but no output schema exists and 'scrobbles' plus the limit parameter make the result shape inferable, so only a small gap remains.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, with clear descriptions for to, from, limit, and username. The description's 'Pass a username unless the server has a local default' mirrors the schema's username description, adding no new meaning, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description 'Get a Last.fm user’s most recent scrobbles' states a specific verb and resource, immediately distinguishing it from siblings like top_items, artist_history, and rediscovery_candidates. The purpose is unambiguous and the resource scope is clear.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No explicit guidance is provided on when to choose this tool over its siblings. The only usage hint, 'Pass a username unless the server has a local default,' addresses parameter handling rather than tool selection. Usage is implied by the purpose statement but not elaborated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
rediscovery_candidatesARead-onlyIdempotent
Find historically significant artists with little or no listening in a recent Last.fm period. Uses an explainable heuristic, not a Last.fm recommendation endpoint.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| username | No | Last.fm username. Optional only when the server has a local default configured. | |
| recentPeriod | No | 3month | |
| historicalPool | No | How many all-time top artists to consider. | |
| minHistoricalPlays | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, openWorldHint, and idempotentHint, so the safety profile is covered. The description adds value by disclosing that it uses an explainable heuristic rather than a Last.fm recommendation endpoint, which clarifies the data source and method. It does not fully explain the heuristic, but that is not required; the note about explainability is a meaningful addition beyond annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two concise sentences, front-loaded with the core purpose and a distinguishing note. Every word contributes to understanding the tool's function and its relationship to Last.fm's native recommendation system. No fluff or repetition.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool has 5 parameters and no output schema, so the description must carry more weight. It explains the purpose and the heuristic nature, but omits any information about return values, pagination, or how the parameters influence results. An agent would not know what output to expect or how to tune the tool, making this incomplete for a parameter-rich tool without an output schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is only 40% (username and historicalPool have descriptions, but limit, recentPeriod, and minHistoricalPlays do not). The tool description itself does not mention any parameters or provide any additional meaning. With low schema coverage, the description carries the burden to explain parameters, and it fails entirely, leaving the agent without guidance on how to set values or interpret their effects.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Find') and resource ('historically significant artists with little or no listening in a recent Last.fm period'). It explicitly distinguishes itself from a recommendation endpoint, which sets it apart from typical recommendation tools. Among siblings (top_items, recent_scrobbles, artist_history), this is clearly about rediscovery candidates, not current top items, recent plays, or a single artist's history.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description clearly implies when to use this tool: when you want to surface under-heard historical artists. It also states what it is not (a recommendation endpoint). However, it does not explicitly name alternative tools or give 'use X instead when Y' guidance. The context is clear but exclusions are only implied, not stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
top_itemsBRead-onlyIdempotent
Get top artists, albums, or tracks for a Last.fm user over a selectable period. Pass a username unless the server has a local default.
| Name | Required | Description | Default |
|---|---|---|---|
| kind | Yes | Whether to return artists, albums, or tracks. | |
| limit | No | ||
| period | No | overall | |
| username | No | Last.fm username. Optional only when the server has a local default configured. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover read-only, idempotent, and open-world behavior, lowering the burden on the description. The description adds a useful note about the server-side local default for username, but it does not disclose other behaviors such as result ordering, pagination, or rate limits.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two concise sentences with no filler. The core function is front-loaded, and the username note is a necessary operational detail.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 4-parameter tool with no output schema, the description covers the essential inputs and one configuration nuance, but it omits any hint of return format, how 'top' is defined, or the meaning of the limit parameter. This leaves some gaps for an agent.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 50%, so the description must compensate. It adds meaning for kind (artists/albums/tracks), period (selectable period), and username (pass unless local default), but it does not mention limit at all. This is partial compensation at best.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('Get') and resource ('top artists, albums, or tracks for a Last.fm user') with a period selector, which clearly conveys the tool's function. It does not explicitly contrast with siblings like recent_scrobbles or artist_history, so it misses the top distinction.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no guidance on when to use this tool instead of recent_scrobbles, artist_history, or rediscovery_candidates. The only usage note is about the username default, which is a parameter detail, not a selection criterion.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
4 tool updates
v0.3.0- First observed
artist_history - First observed
recent_scrobbles - First observed
rediscovery_candidates - First observed
top_items
TDQS
Scored across 4 tools
Each tool targets a clearly distinct purpose: top_items returns rankings, recent_scrobbles returns a listening stream, artist_history checks a specific artist, and rediscovery_candidates surfaces overlooked artists. There is little risk of an agent selecting the wrong tool for a given task.
All four tool names follow the same lowercase snake_case noun-phrase pattern. Though not verb_noun, the convention is perfectly consistent and predictable across the set.
Four tools form a compact, purposeful set for a niche Last.fm listening-history server. Each tool earns its place and the scope feels appropriately focused rather than bloated or thin.
The set covers the core Last.fm user-listening workflow: top items, recent activity, specific artist checks, and rediscovery candidates. Minor gaps like user profile info or detailed artist metadata are absent, but agents can still complete meaningful tasks without major dead ends.
Maintenance
Related MCP Connectors
Read public AT Protocol profiles, records, threads, backlinks and lexicons. No API key required.
Find Bizzy radio stations, read station cards and public author information. Read-only; no playback.
- PithflowOAuthcom.pithflow
Read-only access to your own Pithflow meeting notes, transcripts, dictionary and usage.
Spotify: Spotify Data API for Millions of songs & podcasts, artists, albums, playlists and more.
Related MCP Servers
- FlicenseBqualityDmaintenanceEnables interaction with Last.fm music data including searching for artists, albums, and tracks, accessing user listening history, and managing music preferences. Supports both read-only operations and authenticated write operations like scrobbling and loving tracks.345-
- AlicenseNot gradedqualityAmaintenanceA Model Context Protocol (MCP) server for Last.fm. Gives AI assistants access to your listening history, music discovery, and detailed track/artist/album information.48MIT
- AlicenseBqualityBmaintenanceProvides 41 read-only tools to search and browse Last.fm data, including artists, albums, tracks, user scrobble history, and charts.414 npmMIT
- AlicenseNot gradedqualityBmaintenanceProvides Last.fm listening analytics and recommendations by combining Last.fm and MusicBrainz metadata, maintaining a local listening index, and recording explicit preferences. Enables queries for listening summaries, taste profiles, artist context, and evidence-backed recommendations via MCP tools.MIT