Skip to content

Releases: rianvdm/lastfm-mcp

lastfm-mcp v2.5.0 — Latest MCP protocol support

Choose a tag to compare

@rianvdm rianvdm released this 25 Aug 00:04
1160ec8

The server now speaks the current MCP revision (2026-07-28, the stateless one) natively, while older clients keep working through the SDK's compatibility lane. Tool responses also got smarter about what to call next, and two long-standing crash bugs in the public catalog tools are gone.

Breaking changes

  • The Mcp-Session-Id header is no longer read or echoed, since the 2026-07-28 spec removed protocol sessions. If you connected through the manual /login flow, pass ?session_id= on the /mcp URL, which was always the documented way. Nothing changes for OAuth clients such as Claude.ai, Claude Code, or Claude Desktop.

What's new

  • MCP 2026-07-28 support: server/discover, the _meta request envelope, and the MCP-Protocol-Version, Mcp-Method, and Mcp-Name headers. Clients on the 2024 and 2025 revisions still connect with initialize and get the same tools.
  • Every tool response ends with a "Next steps" block listing the most likely follow-up calls with their exact arguments. Where the response has a clear top item (your top artist this month, the most recent week in a chart list), the first suggestion is filled in with it. The server also ships instructions naming the recommended tool path per entity, so a model lands on the right verb without reading all 21 descriptions.
  • Numeric parameters (limit, page, from, to) accept strings, because some clients send numbers that way. The same bounds still apply.
  • Resource templates advertise a description and MIME type.
  • /mcp is rate limited per IP at 60 requests a minute to protect the shared Last.fm API budget. That is well above what any interactive client does.

Fixes

  • get_album_info, get_track_info, and get_artist_info no longer throw for an album, track, or artist with exactly one tag, one track, or one similar artist, or with none at all. Last.fm sends those as a bare object or leaves the key out; the tools handle all three shapes now. This was producing a few dozen errors a week in production.
  • A failed Last.fm fetch raised a second, unhandled rejection alongside the error the caller already received.
  • The discovery card and server_info reported protocol 2024-11-05. Both now report 2026-07-28.

Under the hood

  • @modelcontextprotocol/server 2.0 and @modelcontextprotocol/client 2.0 replace the v1 SDK, with Cloudflare Agents SDK 0.21 (createMcpHandler from agents/mcp/server) and @cloudflare/workers-oauth-provider 0.10. npm audit on production dependencies reports zero vulnerabilities, down from 14.
  • All tool, prompt, and resource registrations use the register* APIs with z.object() schemas.
  • Two OAuth workarounds for Claude.ai's RFC 8707 resource parameter are gone; the provider handles it correctly now.
  • Test stack is vitest 4, @cloudflare/vitest-pool-workers 0.22, and Node 22. CI runs the suite again (174 tests) after a long stretch with that step disabled. New tests drive a real SDK client through the Worker on both protocol lanes and snapshot the advertised catalogue.
  • Dead code removed: the session-logging utilities, leftover type files, and an unused OAuth registration wrapper.

lastfm-mcp v2.4.0 — Top tracks and 8K fewer lines

Choose a tag to compare

@rianvdm rianvdm released this 30 Apr 20:09
3d3c16c

The big shifts in this release: three new tools, a glassmorphism-redesigned landing page, timezone-aware day boundaries on get_recent_tracks, and a 8,300-line cull of the original session-based worker now that the OAuth path has been the only one in production for a while.

What's new

  • Three new tools. get_top_tracks fills the obvious symmetry gap with the existing get_top_artists and get_top_albums. get_artist_top_tracks and get_artist_top_albums surface an artist's globally most-played catalog — useful for "what's the canonical record by X" questions.
  • Date-aware get_recent_tracks. New date param accepts a YYYY-MM-DD calendar date plus a timezone (IANA name, e.g. America/New_York) and the server computes the correct UTC day boundaries. Way better than juggling from/to Unix timestamps for "what did I listen to yesterday" queries. The response also echoes the queried range back so an LLM can self-verify it asked the right question.
  • Redesigned landing page at lastfm-mcp.com — glassmorphism, animated waves, glow effects.

Fixes

  • get_album_info no longer renders [object Object] when Last.fm returns the album artist as an object instead of a string. Latent bug, fixed via a formatArtist helper that handles both shapes.

Under the hood

  • Deleted the legacy worker. Removed src/index.ts plus the homemade JSON-RPC dispatch layer in src/protocol/ and the SSE transport in src/transport/. The OAuth worker (src/index-oauth.ts) has been the only production deployment for months; the legacy [env.legacy] block in wrangler.toml was never deployed to Cloudflare. Net diff: −8,293 lines, 0 added. Test suite went from 376 tests / 5 failing → 167 tests / 0 failing.
  • Dropped dead deps: crypto-js, @types/crypto-js, oauth-1.0a — zero imports.
  • Removed dead throttle. LastfmClient.throttleRequest was per-request (clients are instantiated per-request in the OAuth worker), so it never observed a previous request — it did nothing while implying rate-limit safety. Existing 429-aware retry handles rate limits correctly.
  • Dynamic tool catalog. The lastfm_auth_status tool list lives in one place now (src/mcp/tools/catalog.ts) instead of being hardcoded in three.

v2.3.1 — Timezone-aware date formatting

Choose a tag to compare

@rianvdm rianvdm released this 17 Mar 19:06

What's new

Track play times in get_recent_tracks now display in the correct timezone instead of silently using UTC. Previously, a track played at 11pm Pacific would show as the next day — causing Claude to say "yesterday" when it was today, or confuse morning/evening.

Changes

  • Added optional timezone parameter to get_recent_tracks (IANA format, e.g. "America/New_York"). Defaults to UTC.
  • All date formatting now uses an explicit UTC timestamp (Mar 17, 2026, 2:04 AM UTC) instead of the runtime-local format (3/17/2026), making dates unambiguous regardless of where the server runs.
  • Invalid timezone strings fall back to UTC with a visible warning.
  • Shared formatTimestamp utility eliminates duplicated date logic across the codebase.

v2.3.0 - Automatic OAuth Browser Flow

Choose a tag to compare

@rianvdm rianvdm released this 15 Mar 21:23
e83b5cc

What's New

This release fixes the authentication experience for all MCP clients. Previously, connecting any client (Claude Code, Claude Desktop, opencode) to the server required manually copying and pasting a login URL. Now the browser opens automatically and the entire auth flow is hands-free.

OAuth Browser Flow Fix

  • Automatic browser open on first connection — Unauthenticated POST /mcp requests now return 401 + WWW-Authenticate: Bearer resource_metadata=... per the MCP OAuth 2.1 spec. Conforming clients (Claude Code, Claude Desktop, opencode) detect this response and open the browser to Last.fm automatically — no copy-paste URL required
  • Preserved manual login path — Clients that previously authenticated via /login continue to work without re-authenticating. The server checks for an existing session via Mcp-Session-Id header + KV lookup before falling through to the OAuth provider
  • Legacy session_id param path unchanged — Direct session-based connections (e.g. ?session_id=...) are unaffected

Security Fix (from v2.2.0 hotfix)

  • JWT timing side-channel — Replaced string comparison of JWT signatures with crypto.subtle.timingSafeEqual() to prevent timing-based token forgery attacks
  • SSE global mutable state — Eliminated a shared mutable Map across requests in the SSE transport layer that could leak session data between concurrent users

Test Infrastructure

  • CJS ajv compatibility — The Cloudflare Workers test pool (@cloudflare/vitest-pool-workers) couldn't load the nested CommonJS ajv module from @modelcontextprotocol/sdk. Fixed by aliasing ajv and ajv-formats to minimal ESM stubs in vitest.config.mts, restoring full test suite execution
  • New OAuth test suite — 34 tests across 3 files covering: unauthenticated 401 behavior, OAuth metadata endpoints, Mcp-Session-Id header routing, and a full 7-step OAuth round-trip (client registration → PKCE authorize → Last.fm callback → token exchange → authenticated MCP call)

Full Changelog

v2.2.0...v2.3.0

v2.2.0 - Security Hardening & MCP Server Review

Choose a tag to compare

@rianvdm rianvdm released this 22 Feb 01:40

What's New

This release addresses all P0 (critical) and P1 (important) findings from a comprehensive security and best-practices review of the MCP server against Cloudflare's MCP server building guidelines.

Security Improvements

  • CSRF protection on login flow/login now sets a _csrf_token secure cookie that is validated on /callback, preventing cross-site request forgery attacks on the OAuth flow
  • Content Security Policy headers — The auth success page is now served with Content-Security-Policy, X-Frame-Options: DENY, and X-Content-Type-Options: nosniff headers. Username and session data are sanitized before rendering
  • Typed OAuth resource param fix — Replaced unsafe (oauthReqInfo as any).resource = undefined with properly typed assertion to prevent audience mismatch when Claude.ai sends the full MCP endpoint URL

Reliability Improvements

  • Error handling on all MCP tools — All 17 tool callbacks (6 public + 11 authenticated) are now wrapped in try/catch with user-friendly error messages via a toolError() helper, preventing unhandled exceptions from crashing tool calls
  • Session lookup bug fixhandleUnauthenticatedMcp now checks KV for existing sessions via Mcp-Session-Id header instead of generating a new UUID on every request. This fixes the issue where login worked but subsequent MCP tool calls couldn't find the session
  • Context-aware success page — Auth success page now shows "close this window" for users arriving from an MCP client session, and config instructions for manual /login visitors

Code Quality

  • Tool code deduplication — Eliminated ~500 lines of duplicated tool registration code between OAuth and non-OAuth paths. Single registerAuthenticatedTools with pluggable AuthMessageConfig, where registerAuthenticatedToolsWithOAuth is a 3-line wrapper
  • Deduplicated routes — Removed 5 duplicate route handlers from oauth-handler.ts that were already handled in index-oauth.ts
  • OAuth server factory — Replaced per-request McpServer creation in OAuth handler with shared createMcpServer() factory
  • ABOUTME comments — All 29 source files now have standardized // ABOUTME: header comments
  • Dynamic base URLs — Replaced hardcoded URLs with new URL(request.url).origin derivation
  • Bundle size reduced — From 2824 KiB to 2726 KiB (-98 KiB) by removing duplicate client imports

New Files

  • src/utils/security.ts — CSRF token generation/validation, CSP header builder, HTML sanitization
  • src/mcp/tools/error-handler.ts — Reusable toolError() helper for MCP tool error responses
  • docs/MCP-SERVER-REVIEW.md — Full assessment document with all findings
  • docs/TODO.md — P2 cleanup items for future work

Full Changelog

v2.1.1...v2.2.0

v2.1.1

Choose a tag to compare

@rianvdm rianvdm released this 24 Jan 13:12

What's New

Unauthenticated MCP Access

MCP clients that don't support OAuth 2.1 (like Antigravity, Windsurf) can now connect and use public tools without authentication.

  • Public tools work immediately - track info, artist info, album info, similar artists/tracks
  • Authenticated tools prompt for login - when you try to access personal data, you'll get a helpful message with login instructions
  • Session ID support - the server generates and returns an Mcp-Session-Id header for session continuity

Redesigned Setup Documentation

The marketing page setup section has been completely redesigned:

  • Vertical list layout instead of cramped grid
  • Complete JSON configs for each client (not just snippets)
  • Added setup instructions for:
    • Claude.ai / Claude Desktop
    • Windsurf / Antigravity
    • Claude Code
    • OpenCode
    • Cursor
    • Continue.dev / Zed / Other MCP Clients

Other Changes

  • Standardized test file naming (*.test.ts)
  • Fixed auth_statuslastfm_auth_status typo in README
  • Added implementation plan documentation

Full Changelog

  • Allow unauthenticated MCP initialization for non-OAuth clients
  • Redesign setup section with complete client configurations
  • Add OpenCode setup with correct config format

v2.1.0 - Marketing Page Redesign

Choose a tag to compare

@rianvdm rianvdm released this 12 Dec 22:11

What's New

  • Dark theme with Last.fm red (#d51007) accents
  • Updated setup instructions for Claude.ai, Windsurf, and other MCP clients
  • Sample queries section in 2×2 grid layout
  • Copy buttons on code blocks
  • Red headphone SVG favicon
  • Cleaner, more minimal design

v2.0.0 - OAuth 2.0 Support for All Clients

Choose a tag to compare

@rianvdm rianvdm released this 10 Dec 23:43

Major release with full OAuth 2.0 support for Claude.ai, Claude Desktop, Claude Code, and Windsurf.

What's New

OAuth 2.0 Authentication

  • Full OAuth 2.0 support now works with all major MCP clients
  • No more manual session URL workarounds needed
  • Seamless browser-based authentication flow
  • Persistent sessions across conversations

Bug Fixes

  • Fixed OAuth token audience mismatch with Claude.ai
  • Clear resource parameter in authorize handler to prevent audience being set
  • Strip resource parameter from token requests
  • Updated oauth-protected-resource to return base URL without path

Documentation

Breaking Changes

  • Old OAuth grants have been invalidated (users need to re-authenticate once)

Last.fm MCP Server v1.0.0 - Official Launch

Choose a tag to compare

@rianvdm rianvdm released this 26 Jun 16:45

Hey y'all, happy to call this the first stable release of the Last.fm MCP Server! This production-ready server bridges AI assistants with Last.fm's comprehensive music database.

🌟 What's Included

🎧 Personal Music Data

  • Recent listening history with pagination
  • Top artists, albums, and loved tracks
  • Comprehensive listening statistics
  • Personalized music recommendations

🕰️ Temporal QueriesNew Feature

  • Ask "When did I start listening to Led Zeppelin?"
  • Explore "What was I obsessed with in summer 2023?"
  • Access your complete Last.fm listening history by time period
  • Weekly artist and track charts from any date range

🎵 Public Music Information

  • Detailed track, artist, and album information
  • Music discovery with similar artists and tracks
  • Rich metadata and music recommendations

🔐 Secure & Reliable

  • Last.fm Web Authentication with 7-day sessions
  • Smart caching system optimized for different data types
  • Rate limiting and retry logic built-in
  • Global edge deployment on Cloudflare Workers

🚀 Getting Started

Add to your Claude Desktop config:

 {
   "mcpServers": {
     "lastfm": {
       "command": "npx",
       "args": ["mcp-remote", "https://lastfm-mcp-prod.rian-db8.workers.dev/sse"]
     }
   }
 }

Then ask Claude questions like:

  • "What are my recent tracks?"
  • "When did I start listening to [artist]?"
  • "What was I listening to in [time period]?"
  • "Find artists similar to my favorites"

🎯 Perfect For

  • Music enthusiasts who want AI-powered music insights
  • Developers building music-related AI applications
  • Data analysts exploring personal listening patterns
  • Anyone curious about their musical journey over time

📚 Full Documentation

See the README.md for complete setup instructions, API documentation, and examples.