Atlas / MCP servers / rianvdm / Last.fm MCP Server

Last.fm MCP ServerBLOCK

mcp/rianvdm/last-fm

An MCP server that provides seamless access to a user's Last.fm listening data and music information via AI assistants like Claude.

Verdict
BLOCK
Grade
F
Trust score
48 /100
Exposed tools
21 21r · 0w · 0d
Transport
streamable-http
License
MIT
Stars
49
01

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

  1. Open Settings -> Connectors -> Add Custom Connector
  2. Enter https://lastfm-mcp.com/mcp
  3. 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

Read from source at commit 081951eda99fOBSERVED · 2026-10-08
02

Connect

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-code
claude mcp add lastfm-mcp -- npx -y [email protected]
claude-desktop
{
  "mcpServers": {
    "lastfm-mcp": {
      "command": "npx",
      "args": [
        "-y",
        "[email protected]"
      ]
    }
  }
}
03

Exposed tools (21)

21 read · 0 write · 0 destructive.

ToolRiskDescription
get_album_inforead
get_artist_inforead
get_artist_top_albumsread
get_artist_top_tracksread
get_listening_statsread
get_loved_tracksread
get_music_recommendationsread
get_recent_tracksread
get_similar_artistsread
get_similar_tracksread
get_top_albumsread
get_top_artistsread
get_top_tracksread
get_track_inforead
get_user_inforead
get_weekly_artist_chartread
get_weekly_chart_listread
get_weekly_track_chartread
lastfm_auth_statusread
pingread
server_inforead
04

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.

LayerWhat it checksResult
L0Provenance & inventoryWARN
L1Static analysis of the codeFAIL
L2Instruction surface (what it tells the agent)WARN
L3Class-specific surfaceWARN
L4Behavioural (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)

HIGHCode injection · code.eval_exec · CWE-78, CWE-94, CWE-95
.build/tools/worker-configuration.d.ts:2366
exec(input?: string | URLPatternInit, baseURL?: string): URLPatternResult | null
Why it matters. evaluates text as code
Fix. remove; use a parser or a dispatch table
HIGHCode injection · code.eval_exec · CWE-78, CWE-94, CWE-95
.build/tools/worker-configuration.d.ts:5125
exec(query: string): Promise<D1ExecResult>
Why it matters. evaluates text as code
Fix. remove; use a parser or a dispatch table
MEDIUMInventory / provenance · inv.symlink · CWE-1104
.windsurf/skills/building-mcp-server-on-cloudflare
.windsurf/skills/building-mcp-server-on-cloudflare
Why it matters. link not followed
MEDIUMInventory / provenance · inv.symlink · CWE-1104
.windsurf/skills/cloudflare
.windsurf/skills/cloudflare
Why it matters. link not followed
MEDIUMInventory / provenance · inv.symlink · CWE-1104
.windsurf/skills/workers-best-practices
.windsurf/skills/workers-best-practices
Why it matters. link not followed
MEDIUMInventory / provenance · inv.symlink · CWE-1104
.windsurf/skills/wrangler
.windsurf/skills/wrangler
Why it matters. link not followed
MEDIUMHard-coded secrets · secret.generic · CWE-798, CWE-321
.agents/skills/cloudflare/references/turn/gotchas.md:102
const secret = 'your-turn-key-secret';
MEDIUMPrompt injection · prompt.hidden_style · CWE-94, CWE-1427
.agents/skills/cloudflare/references/turnstile/patterns.md:147
<form id="protected-form" style="display: none;">
MEDIUMAuth / authz · mcp.remote_no_auth · CWE-287, CWE-862
streamable-http
Why it matters. a network transport with no auth environment variable found
Fix. require a token
LOWInventory / provenance · inv.hidden_file · CWE-1104
.dev.vars.example
.dev.vars.example
Why it matters. hidden member outside the usual dotfiles
Fix. review its purpose
LOWInventory / provenance · inv.hidden_file · CWE-1104
.eslintrc.cjs
.eslintrc.cjs
Why it matters. hidden member outside the usual dotfiles
Fix. review its purpose
LOWInventory / provenance · inv.hidden_file · CWE-1104
.prettierignore
.prettierignore
Why it matters. hidden member outside the usual dotfiles
Fix. review its purpose
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
src/mcp/resources/lastfm.ts:5
import { CachedLastfmClient } from '../../clients/cachedLastfm'
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
src/mcp/tools/authenticated.ts:6
import { CachedLastfmClient } from '../../clients/cachedLastfm'
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
src/mcp/tools/authenticated.ts:10
import { buildNextSteps } from '../../utils/breadcrumb'
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
src/mcp/tools/authenticated.ts:11
import { formatTimestamp, getDayBoundsUTC } from '../../utils/dateFormat'
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
src/mcp/tools/public.ts:6
import { CachedLastfmClient } from '../../clients/cachedLastfm'
LOWNetwork egress · net.raw_ip · CWE-200, CWE-319
.agents/skills/cloudflare/references/miniflare/api.md:181
console.log(`Server running at ${url}`); // http://127.0.0.1:8787
LOWNetwork egress · net.raw_ip · CWE-200, CWE-319
test/oauth-cimd.test.ts:44
redirectUris: ['http://localhost/callback', 'http://127.0.0.1/callback'],
LOWNetwork egress · net.raw_ip · CWE-200, CWE-319
test/oauth-cimd.test.ts:50
redirectUris: ['http://127.0.0.1:33418/', 'https://vscode.dev/redirect'],
LOWObfuscation / stealth · obf.decode_call · CWE-506, CWE-94
.build/tools/worker-configuration.d.ts:216
atob(data: string): string
LOWObfuscation / stealth · obf.decode_call · CWE-506, CWE-94
.build/tools/worker-configuration.d.ts:310
declare function atob(data: string): string
LOWObfuscation / stealth · obf.decode_call · CWE-506, CWE-94
src/auth/jwt.ts:145
return atob(base64)
LOWObfuscation / stealth · obf.decode_call · CWE-506, CWE-94
test/auth/jwt.test.ts:127
const header = JSON.parse(atob(parts[0].replace(/-/g, '+').replace(/_/g, '/')))
LOWObfuscation / stealth · obf.decode_call · CWE-506, CWE-94
test/auth/jwt.test.ts:146
const payload = JSON.parse(atob(paddedPayload.replace(/-/g, '+').replace(/_/g, '/')))

Gates applied: no_behavioural_pass.

Audited 2026-10-08 · audit v0.4.1 · source sha 081951eda99ffull audit observations/trust-audit/mcp-server/rianvdm__last-fm.json · Report an issue / request a re-scan
05

Audit history

Every audit this server has had. A grade with a past is a grade somebody is still checking.

DateSourceVerdictGradeScoreChange
2026-10-08081951eda99fBLOCKF48first audit
06

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.

Advertisement