control_playback
Control Spotify playback by playing, pausing, skipping tracks, or adjusting volume through the Spotify MCP Server.
Instructions
Control Spotify playback (play, pause, skip, volume). Note: skip-next and skip-previous will only skip once per call.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| action | Yes | Action to perform. Use skip-next or skip-previous to skip to the next/previous track ONCE. | |
| value | No | Volume percentage (0-100) for volume action | |
| deviceId | No | Optional device ID |
Implementation Reference
- src/tools/playback.ts:7-64 (handler)The core handler function `controlPlayback` that executes the tool logic. It handles actions like play, pause, skip-next/previous (with rate limiting), and volume control using the SpotifyClient.export async function controlPlayback( client: SpotifyClient, action: 'play' | 'pause' | 'skip-next' | 'skip-previous' | 'volume', value?: number, deviceId?: string ) { switch (action) { case 'play': await client.resume(deviceId); return { success: true, message: 'Playback resumed' }; case 'pause': await client.pause(deviceId); return { success: true, message: 'Playback paused' }; case 'skip-next': { const now = Date.now(); const lastTime = lastSkipTime.get('skip-next') || 0; if (now - lastTime < SKIP_COOLDOWN_MS) { return { success: true, message: 'Skipped to next track (rate limited - already skipped recently)' }; } await client.skipToNext(deviceId); lastSkipTime.set('skip-next', now); return { success: true, message: 'Skipped to next track once' }; } case 'skip-previous': { const now = Date.now(); const lastTime = lastSkipTime.get('skip-previous') || 0; if (now - lastTime < SKIP_COOLDOWN_MS) { return { success: true, message: 'Skipped to previous track (rate limited - already skipped recently)' }; } await client.skipToPrevious(deviceId); lastSkipTime.set('skip-previous', now); return { success: true, message: 'Skipped to previous track once' }; } case 'volume': if (value === undefined || value < 0 || value > 100) { throw new Error('Volume must be between 0 and 100'); } await client.setVolume(value, deviceId); return { success: true, message: `Volume set to ${value}%` }; default: throw new Error(`Unknown action: ${action}`); } }
- src/server.ts:147-169 (registration)Registration of the 'control_playback' tool in the MCP server's ListTools response. Includes the tool name, description, and input schema definition.{ name: 'control_playback', description: 'Control Spotify playback (play, pause, skip, volume). Note: skip-next and skip-previous will only skip once per call.', inputSchema: { type: 'object', properties: { action: { type: 'string', enum: ['play', 'pause', 'skip-next', 'skip-previous', 'volume'], description: 'Action to perform. Use skip-next or skip-previous to skip to the next/previous track ONCE.', }, value: { type: 'number', description: 'Volume percentage (0-100) for volume action', }, deviceId: { type: 'string', description: 'Optional device ID', }, }, required: ['action'], }, },
- src/server.ts:150-168 (schema)The input schema definition for the 'control_playback' tool, specifying parameters like action (enum), optional value for volume, and deviceId.inputSchema: { type: 'object', properties: { action: { type: 'string', enum: ['play', 'pause', 'skip-next', 'skip-previous', 'volume'], description: 'Action to perform. Use skip-next or skip-previous to skip to the next/previous track ONCE.', }, value: { type: 'number', description: 'Volume percentage (0-100) for volume action', }, deviceId: { type: 'string', description: 'Optional device ID', }, }, required: ['action'], },
- src/server.ts:336-350 (helper)The dispatch handler in the MCP server's CallToolRequestSchema that invokes the controlPlayback function with parsed arguments and returns the result.case 'control_playback': const controlResult = await playbackTools.controlPlayback( client, args?.action as 'play' | 'pause' | 'skip-next' | 'skip-previous' | 'volume', args?.value as number | undefined, deviceManager.getDevice(args?.deviceId as string | undefined) ); return { content: [ { type: 'text', text: JSON.stringify(controlResult, null, 2), }, ], };
- src/tools/playback.ts:3-5 (helper)Helper variables for rate limiting skip actions to prevent loops (lastSkipTime map and cooldown constant). Used within the controlPlayback handler.// Rate limiting for skip actions to prevent loops const lastSkipTime = new Map<string, number>(); const SKIP_COOLDOWN_MS = 1000; // 1 second cooldown between skips