SpotifyPlayback
Control Spotify playback by getting current track info, starting/resuming music, pausing playback, or skipping tracks using the Spotify MCP Server.
Instructions
Manages the current playback with the following actions: - get: Get information about user's current track. - start: Starts of resumes playback. - pause: Pauses current playback. - skip: Skips current track.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| action | Yes | Action to perform: 'get', 'start', 'pause' or 'skip'. | |
| num_skips | No | Number of tracks to skip for `skip` action. | |
| track_id | No | Specifies track to play for 'start' action. If omitted, resumes current playback. |
Implementation Reference
- src/spotify_mcp/server.py:64-74 (schema)Pydantic input schema for the SpotifyPlayback tool, defining actions: get, start, pause, skip with relevant parameters.class Playback(ToolModel): """Manages the current playback with the following actions: - get: Get information about user's current track. - start: Starts of resumes playback. - pause: Pauses current playback. - skip: Skips current track. """ action: str = Field(description="Action to perform: 'get', 'start', 'pause' or 'skip'.") track_id: Optional[str] = Field(default=None, description="Specifies track to play for 'start' action. If omitted, resumes current playback.") num_skips: Optional[int] = Field(default=1, description="Number of tracks to skip for `skip` action.")
- src/spotify_mcp/server.py:97-108 (registration)Registers the SpotifyPlayback tool (as 'SpotifyPlayback') in the MCP server's list_tools handler using Playback.as_tool().@server.list_tools() async def handle_list_tools() -> list[types.Tool]: """List available tools.""" logger.info("Listing available tools") tools = [ Playback.as_tool(), Search.as_tool(), Queue.as_tool(), GetInfo.as_tool(), ] logger.info(f"Available tools: {[tool.name for tool in tools]}") return tools
- src/spotify_mcp/server.py:121-162 (handler)Core handler logic inside @server.call_tool() for executing SpotifyPlayback tool actions by dispatching to spotify_client methods.case "Playback": action = arguments.get("action") match action: case "get": logger.info("Attempting to get current track") curr_track = spotify_client.get_current_track() if curr_track: logger.info(f"Current track retrieved: {curr_track.get('name', 'Unknown')}") return [types.TextContent( type="text", text=json.dumps(curr_track, indent=2) )] logger.info("No track currently playing") return [types.TextContent( type="text", text="No track playing." )] case "start": logger.info(f"Starting playback with arguments: {arguments}") spotify_client.start_playback(track_id=arguments.get("track_id")) logger.info("Playback started successfully") return [types.TextContent( type="text", text="Playback starting with no errors." )] case "pause": logger.info("Attempting to pause playback") spotify_client.pause_playback() logger.info("Playback paused successfully") return [types.TextContent( type="text", text="Playback paused successfully." )] case "skip": num_skips = int(arguments.get("num_skips", 1)) logger.info(f"Skipping {num_skips} tracks.") spotify_client.skip_track(n=num_skips) return [types.TextContent( type="text", text="Skipped to next track." )]
- spotify_client.get_current_track(): Fetches and parses current playback track information using Spotipy.def get_current_track(self) -> Optional[Dict]: """Get information about the currently playing track""" try: # current_playback vs current_user_playing_track? current = self.sp.current_user_playing_track() if not current: self.logger.info("No playback session found") return None if current.get('currently_playing_type') != 'track': self.logger.info("Current playback is not a track") return None track_info = utils.parse_track(current['item']) if 'is_playing' in current: track_info['is_playing'] = current['is_playing'] self.logger.info( f"Current track: {track_info.get('name', 'Unknown')} by {track_info.get('artist', 'Unknown')}") return track_info except Exception as e: self.logger.error("Error getting current track info", exc_info=True) raise
- spotify_client.start_playback(track_id): Starts or resumes playback of specified track or current, using Spotipy API.def start_playback(self, track_id=None, device=None): """ Starts track playback. If track_id is omitted, resumes current playback. - track_id: ID of track to play, or None. """ try: if not track_id: if self.is_track_playing(): self.logger.info("No track_id provided and playback already active.") return if not self.get_current_track(): raise ValueError("No track_id provided and no current playback to resume.") uris = [f'spotify:track:{track_id}'] if track_id else None device_id = device.get('id') if device else None result = self.sp.start_playback(uris=uris, device_id=device_id) self.logger.info(f"Playback started successfully{' for track_id: ' + track_id if track_id else ''}") return result except Exception as e: self.logger.error(f"Error starting playback: {str(e)}", exc_info=True) raise