Skip to content

Latest commit

 

History

History
243 lines (203 loc) · 14.8 KB

File metadata and controls

243 lines (203 loc) · 14.8 KB

Changelog

All notable changes to this project will be documented in this file.

The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.

[Unreleased]

Fixed

  • Spotify error bodies no longer leak into MCP responses. StartPlaybackAsync and ActivateDeviceAsync in SpotifyStreamer.cs were writing Spotify's raw HTTP error JSON to stdout via Console.WriteLine; because that JSON appears before the CLI's own final response, MCP's parser was picking up the leak (e.g. {"error":{"status":404,"message":"Not found."}}) instead of the CLI's structured {success:false, message:...} output. Rerouted to stderr.
  • MCP parseJsonOutput prefers the last balanced JSON in stdout (lfm-mcp-release/server-core.js), not the first. Any pre-payload stdout noise (Spotify errors, progress lines, future leaks) is now harmless as long as the CLI writes its structured response last.
  • lfm_play_now no longer requires a manual lfm_activate_device round-trip when the target Spotify device is idle. PlayNowFromUrisAsync now calls EnsurePlaybackActiveAsync before starting playback, mirroring the pattern QueueFromUrisAsync has always used. Eliminates the recurring NO_ACTIVE_DEVICE friction.

[1.12.0] - 2026-07-11

Added

  • lfm config spotify-auth — authorize or re-authorize Spotify on demand, starting a fresh (and now tracked) 6-month authorization. Prints the next re-auth due date and the commands to propagate the token to other machines. Every reauth error message has advertised this command since 1.11.0; now it exists.
  • lfm config import <file> --spotify-auth — import only the Spotify authorization (client credentials, refresh token, authorization date), leaving machine-specific settings (Sonos URL, default device/player) untouched. Intended for syncing a fresh authorization to other laptops via the OneDrive-synced staging config.
  • Spotify authorization expiry tracking — new SpotifyConfig.AuthorizedAt stamp set on every OAuth code exchange. lfm api-status (text and --json) now reports authorization status, the ~6-month re-auth due date, and warns inside the final 14 days. Verified against Spotify's 2026-06-18 policy: expiry is absolute from the original authorization, not from last refresh.
  • ./deploy-to-spark.sh --config-only — push config.json and recreate the container without a source sync or image rebuild; the fast path for the 6-monthly re-auth ritual.

Fixed

  • Rotated refresh tokens are now persisted — the refresh path previously discarded any new refresh token Spotify returned; per the documented contract it is now saved (without resetting the authorization clock).
  • Transient refresh failures no longer force a full interactive OAuth flow — network blips now surface as retryable errors that keep the stored token.
  • Bare code=... paste during the OAuth flow no longer crashes with UriFormatException.
  • Stale lfm spotify auth references corrected to lfm config spotify-auth.

Security (HTTP MCP server)

  • Bearer-token authentication implemented — enforced on /mcp when AUTH_TOKEN is set (timing-safe comparison, 401 otherwise); /health stays open. Previously AUTH_TOKEN was advertised by the entrypoint and docs but never read. Runs open when unset (required until claude.ai custom connectors' request-headers beta is broadly available).
  • CORS hardened — dropped credentials: true and the * wildcard; browser cross-origin requests are denied by default (ALLOWED_ORIGINS empty). MCP clients send no Origin header and are unaffected.
  • Removed error.stack from 500 response bodies; committed bearer token removed from .mcp.json (now ${LFM_AUTH_TOKEN} env expansion); .env.example rewritten to match the implemented auth (the GitHub-OAuth design it described was never built).

MCP Server (v0.7.0)

  • lfm_recommendations, lfm_toptracks, lfm_mixtape, and lfm_recent_tracks now pass structured CLI errors through (spotify_reauth_required etc.) instead of masking them with success: true and empty results
  • Reauth action guidance now describes the real recovery ritual (re-auth on a laptop, push config to the server)

[1.11.0] - 2026-06-18

Added

  • lfm album-tracks command / lfm_album_tracks MCP tool — canonical Spotify tracklist for an album, returning track number, disc number, duration, and per-track artist attribution
    • Plugs the well-known LLM blind spot on album track positions (the "Tom The Model is the closer" failure mode)
    • Uses GET /v1/albums/{id}/tracks with pagination via next for albums >50 tracks
    • Same disambiguation contract as lfm_play_now (multiple-versions error + exactMatch retry)
    • Updated lfm-guidelines.md to route canonical-position questions to the new tool, keeping lfm_check verbose for scrobble-coverage questions

Changed

  • Spotify reauthentication handling (preparing for Spotify's 2026-07-20 6-month refresh-token expiry policy)
    • New SpotifyReauthRequiredException thrown specifically on Spotify's invalid_grant response
    • EnsureValidAccessTokenAsync distinguishes interactive CLI from headless MCP via Console.IsInputRedirected: interactive falls through to OAuth prompt as before; headless throws a clean structured error instead of deadlocking on Console.ReadLine
    • Dead refresh tokens are now discarded from saved config on confirmed invalid_grant (per Spotify's "discard expired tokens" guidance)
    • PlayCommand emits structured { errorCode: "spotify_reauth_required", action: "..." } JSON for MCP consumption
  • Album disambiguation is now case-insensitive — flipped all 5 album exact-match sites from StringComparison.Ordinal to OrdinalIgnoreCase, matching the existing playlist-disambiguation convention. ("Out of Season" now resolves to Spotify's "Out Of Season" without the user needing to mirror Spotify's title-case.)
  • Primary build target is now win-arm64 (laptop upgraded to ARM as of 2026-06)

MCP Server (v0.6.0)

  • New tool: lfm_album_tracks (33 tools total)
  • executeLfmCommand now passes structured-JSON stdout through to the MCP layer on non-zero CLI exit, surfacing handled-error JSON (multiple album versions, Spotify reauth required) instead of swallowing it as a generic "command failed" message

[1.10.0] - 2026-02-28

Fixed

  • Complete Spotify API Migration - All breaking changes from Spotify's Feb 2026 API update now addressed ahead of March 9 deadline
    • Playlist delete endpoint migrated from DELETE /v1/playlists/{id}/followers to DELETE /v1/me/library?uris= (note: uris must be a query parameter, not request body — undocumented by Spotify)
    • Playlist object field rename from tracks to items in SpotifyPlaylistItem model (SpotifyModels.cs)
    • Previously completed: playlist creation endpoint (/me/playlists) and add tracks endpoint (/items)

MCP Server (v0.5.1)

  • Spotify endpoint changes apply to MCP tools that create playlists and manage tracks
  • No new tools or tool changes — all 32 tools remain the same

[1.6.0] - 2025-10-31

Added

Playlist Management Features

  • Play Playlists by Name - New lfm playlist command to play Spotify playlists
    • Fuzzy name matching for easy playlist discovery
    • Exact match mode with --exact-match flag for disambiguation
    • Works with both Spotify and Sonos players
    • Supports --player, --device, --room, --json options
  • List All Playlists - New lfm playlists command
    • Shows all user playlists with track counts
    • Indicates owned vs followed playlists
    • JSON output support for programmatic use

MCP Server Enhancements (v0.3.0)

  • New MCP Tools - Added 2 new tools for playlist management (30 tools total)
    • lfm_play_playlist - Play user playlists by name with disambiguation support
    • lfm_get_playlists - Get list of all user playlists with metadata
  • Two-Phase Disambiguation - Same pattern as albums for consistent UX
    • Discovery phase: Fuzzy search shows all matching playlists
    • Exact match phase: Filter for specific playlist when multiple matches found

Technical Improvements

  • Interface Extensions
    • IPlaylistStreamer: Added SearchPlaylistByNameAsync() and PlayPlaylistAsync()
    • ISonosStreamer: Added PlayPlaylistAsync()
  • New Models - PlaylistSearchResult for disambiguation support
  • URI Format Handling
    • Spotify: spotify:playlist:{id}
    • Sonos: spotify:user:spotify:playlist:{id} (required format)

Documentation

  • Updated all documentation with playlist features (README, QUICKSTART, MCP_SETUP)
  • Updated MCP tool counts (28 → 30 tools)
  • Added playlist usage examples and command references
  • Updated CLAUDE.md session notes with implementation details

Technical Details

  • Commands: PlaylistCommand, PlaylistsCommand
  • Command Builders: PlaylistCommandBuilder, PlaylistsCommandBuilder
  • Search Strategy: Reuses existing GetUserPlaylistsAsync() with client-side filtering
  • Design Decision: User playlists only (no public/Spotify playlists for simplicity)

[1.5.1] - 2025-10-17

Fixed

  • GitHub Release Automation - Fixed automated release process to enable installation scripts
    • Ensured GitHub Actions workflow runs on tag push
    • Creates proper GitHub Release with all platform binaries
    • Fixes installation scripts that depend on GitHub Releases

Documentation

  • User Documentation Suite - Comprehensive documentation for end users
    • Created INSTALL.md - Platform-specific installation guide
    • Created QUICKSTART.md - 5-minute getting started guide
    • Created MCP_SETUP.md - Claude Code/Desktop integration setup
    • Created TROUBLESHOOTING.md - Common issues reference
    • Updated README.md to user-friendly landing page
    • Created RELEASE.md - Release process documentation

Maintenance

  • Repository Cleanup - Removed legacy files and improved organization
    • Removed lfm-mcp-prototype directory (2,061 files including node_modules)
    • Removed old planning docs and test files from git
    • Moved development docs to docs/ folder
    • Updated .gitignore to prevent re-adding legacy files

1.5.0 - 2025-10-17

Added

MCP Server Enhancements (v0.2.0)

  • "Listen Before You Speak" methodology - Core workflow guidance for LLM interactions
    • Emphasizes data → think → more data → think → narrative pattern
    • Prevents starting narratives before completing research phase
  • "Using lfm_recommendations - LLM Reasoning First" - Guidelines for proper tool usage
    • Emphasizes LLM musical knowledge over algorithmic recommendations
    • Clear guidance on when NOT to use recommendations (well-known artists)
    • Proper workflow: LLM reasoning first, optionally supplement with tool
  • "Playback State Awareness" - Mandatory workflow before playback suggestions
    • Trigger words identification ("I've queued", "Want me to queue", etc.)
    • Required state checks: recent_tracks + current_track before suggesting playback
    • Response templates for data-informed suggestions

Features

  • Sonos Integration - Full playback support via node-sonos-http-api
    • Unified play command supporting both Spotify and Sonos
    • Room management and device routing
    • Config-driven defaults (DefaultPlayer, DefaultRoom)
  • Recent Tracks Feature - Temporal listening history with chronological ordering
    • Most recent first ordering
    • Configurable hours lookback parameter
    • Perfect for detecting listening patterns
  • Spotify Playback Controls - Comprehensive playback management
    • Play now / queue functionality
    • Pause, resume, skip commands
    • Current track status
    • Device activation support
  • Album Disambiguation - Handle tracks on multiple albums
    • Detect and report multiple album versions
    • Allow track + album parameter combination
    • User preference for studio vs live/greatest hits versions
  • API Status Checker - Diagnose Last.fm connectivity issues
    • Health status for multiple endpoints
    • Verbose mode with HTTP details
    • JSON output for monitoring/automation
  • Parallel API Processing - Batch processing for deep searches
    • Configurable concurrent API calls (default: 5)
    • Intelligent rate limiting (1 second between batches)
    • Significant speedup for artist-tracks/artist-albums deep searches

Improved

  • MCP Parser - Fixed position-based JSON extraction for array-root responses
    • Correctly handles both object-root and array-root JSON structures
    • Helper functions: extractArray() and extractObject() with fallback logic
  • Token Optimization - ~50% reduction in MCP response tokens
    • Added compact helper functions (compactAlbum, compactArtist, compactTrack)
    • Strip URLs and MBIDs that LLMs can't use
    • Applied to lfm_albums, lfm_artists, lfm_tracks handlers
  • Spotify Authentication - Improved resilience
    • Changed StartPlaybackAsync signature from string to List
    • Ensures atomic album playback (all tracks in one API call)
    • Prevents race conditions in track ordering
  • Documentation Refactoring - Split CLAUDE.md into focused files
    • Created SESSION_HISTORY.md - 7 archived sessions
    • Created IMPLEMENTATION_NOTES.md - Technical reference
    • Created LESSONS_LEARNED.md - Debugging patterns and best practices
    • CLAUDE.md reduced by 53% while maintaining current work focus

Fixed

  • Album Queueing - Fixed missing/reordered tracks in Spotify album playback
    • Changed from 12 separate API calls to ONE atomic call
    • Supports up to 100 URIs in one request
  • Depth Parameter Clarification - Corrected understanding in guidelines
    • Depth = popularity ranking (top N by play count), NOT chronological
    • Updated guidelines to recommend deep:true as default
  • Cache Control - Added support for cache control in recent command
    • Respects cache expiry settings
    • Configurable throttling behavior

1.4.0 - Previous Release

Added

  • Enhanced cache system with comprehensive management
  • Comprehensive parameter validation and API improvements
  • Tag filtering system for recommendations
  • Recommendation diversity controls (totalArtists/totalTracks)
  • Artist-specific track and album search
  • Last.fm autocorrect support for artist name matching

Improved

  • Service layer architecture refactoring
  • Date range support across all commands
  • Unicode symbol support with auto-detection
  • API throttling configuration (default: 200ms)

1.0.0 - Initial Release

Added

  • Core Last.fm API integration
  • Basic commands: artists, tracks, albums
  • File-based caching system
  • Cross-platform support (Windows, Linux, WSL)
  • Configuration management
  • Spotify basic integration