Last.fm MCP ServerBLOCK
An MCP server that provides seamless access to a user's Last.fm listening data and music information via AI assistants like Claude.
Overview
From the repository's own README, as read at the audited commit. Badges and raw HTML are left out.
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.
Runs on Cloudflare Workers with OAuth 2.0 authentication. Public tools (track info, artist info, similar artists) work without signing in -- connect your Last.fm account to access personal listening data.
Quick start
Claude.ai / Claude Desktop
- Open Settings -> Connectors -> Add Custom Connector
- Enter
https://lastfm-mcp.com/mcp - Sign in to Last.fm when prompted
Claude Code
claude mcp add --transport http lastfm "https://lastfm-mcp.com/mcp"
Windsurf
Add to ~/.codeium/windsurf/mcp_config.json:
{
"mcpServers": {
"lastfm": {
"serverUrl": "https://lastfm-mcp.com/mcp"
}
}
}Other MCP clients
For clients that don't support remote servers directly (Continue.dev, Zed, etc.), use mcp-remote:
{
"mcpServers": {
"lastfm": {
"command": "npx",
"args": ["-y", "mcp-remote", "https://lastfm-mcp.com/mcp"]
}
}
}MCP Inspector
npx @modelcontextprotocol/inspector https://lastfm-mcp.com/mcp
Authentication
The server uses OAuth 2.0. When you connect from a supported client, your browser opens to Last.fm to authorize access. Tokens persist across sessions.
Public tools work without signing in. You only need to connect your account for personal listening data.
Available tools
Public tools
081951eda99fOBSERVED · 2026-10-08Connect
Built from this server's own package name, version and transport as found in its source — not copied from anyone's documentation, so it cannot drift against a page we do not control.
claude mcp add lastfm-mcp -- npx -y [email protected]
{
"mcpServers": {
"lastfm-mcp": {
"command": "npx",
"args": [
"-y",
"[email protected]"
]
}
}
}Exposed tools (21)
21 read · 0 write · 0 destructive.
| Tool | Risk | Description |
|---|---|---|
get_album_info | read | |
get_artist_info | read | |
get_artist_top_albums | read | |
get_artist_top_tracks | read | |
get_listening_stats | read | |
get_loved_tracks | read | |
get_music_recommendations | read | |
get_recent_tracks | read | |
get_similar_artists | read | |
get_similar_tracks | read | |
get_top_albums | read | |
get_top_artists | read | |
get_top_tracks | read | |
get_track_info | read | |
get_user_info | read | |
get_weekly_artist_chart | read | |
get_weekly_chart_list | read | |
get_weekly_track_chart | read | |
lastfm_auth_status | read | |
ping | read | |
server_info | read |
Trust audit
BLOCKgrade F · trust 48/100 Do not install this without reading the findings. The audit found something that could harm you or your machine.
| Layer | What it checks | Result |
|---|---|---|
| L0 | Provenance & inventory | WARN |
| L1 | Static analysis of the code | FAIL |
| L2 | Instruction surface (what it tells the agent) | WARN |
| L3 | Class-specific surface | WARN |
| L4 | Behavioural (sandbox) | SKIPPED |
What the source does
- Filesystem
- declared (5 observation(s))
- Network
- declared (10 observation(s))
- Shell
- declared (2 observation(s))
- Dependencies
- not all pinned
- Secrets in source
- found
Findings (25)
exec(input?: string | URLPatternInit, baseURL?: string): URLPatternResult | null
exec(query: string): Promise<D1ExecResult>
.windsurf/skills/building-mcp-server-on-cloudflare
.windsurf/skills/cloudflare
.windsurf/skills/workers-best-practices
.windsurf/skills/wrangler
const secret = 'your-turn-key-secret';
<form id="protected-form" style="display: none;">
streamable-http
.dev.vars.example
.eslintrc.cjs
.prettierignore
import { CachedLastfmClient } from '../../clients/cachedLastfm'import { CachedLastfmClient } from '../../clients/cachedLastfm'import { buildNextSteps } from '../../utils/breadcrumb'import { formatTimestamp, getDayBoundsUTC } from '../../utils/dateFormat'import { CachedLastfmClient } from '../../clients/cachedLastfm'console.log(`Server running at ${url}`); // http://127.0.0.1:8787redirectUris: ['http://localhost/callback', 'http://127.0.0.1/callback'],
redirectUris: ['http://127.0.0.1:33418/', 'https://vscode.dev/redirect'],
atob(data: string): string
declare function atob(data: string): string
return atob(base64)
const header = JSON.parse(atob(parts[0].replace(/-/g, '+').replace(/_/g, '/')))
const payload = JSON.parse(atob(paddedPayload.replace(/-/g, '+').replace(/_/g, '/')))
Gates applied: no_behavioural_pass.
081951eda99ffull audit observations/trust-audit/mcp-server/rianvdm__last-fm.json · Report an issue / request a re-scanAudit history
Every audit this server has had. A grade with a past is a grade somebody is still checking.
| Date | Source | Verdict | Grade | Score | Change |
|---|---|---|---|---|---|
| 2026-10-08 | 081951eda99f | BLOCK | F | 48 | first audit |
Questions
What is the Last.fm MCP server?
An MCP server that provides seamless access to a user's Last.fm listening data and music information via AI assistants like Claude.
What tools does Last.fm expose?
21 in total: 21 read-only, 0 that write, and 0 that can delete or overwrite. Every one is listed on this page with its risk.
Is Last.fm safe to connect to an agent?
No — not without reading the findings first. The audit graded it F (48/100) and found 2 critical or high issues in the source. Each one is listed on this page with the file and line it is on.
What credentials does Last.fm need?
No credential environment variables were found in its source, so it appears to need none.
How does Last.fm run?
It speaks streamable-http, so it runs as a service you connect to over the network. It is published on npm as lastfm-mcp at 2.6.0.
How current is this page?
The grade is for one exact copy of the source (081951eda99f), read on 2026-10-08. The repository is watched and re-audited when it changes.