Skip to main content
Glama

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
NameRequiredDescriptionDefault
actionYesAction to perform. Use skip-next or skip-previous to skip to the next/previous track ONCE.
valueNoVolume percentage (0-100) for volume action
deviceIdNoOptional device ID

Implementation Reference

  • 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'],
      },
    },
  • 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'],
    },
  • 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),
          },
        ],
      };
  • 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

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Ackberry/spotify_mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server