Skip to main content
Glama
igorgarbuz

Spotify MCP Node Server

by igorgarbuz

getUserTopItems

Retrieve a user's most listened to artists or tracks from Spotify, with options to filter by time period and quantity.

Instructions

Get a list of the user's top artists or tracks

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
typeYesThe type of items to get top for. Must be "artists" or "tracks"
time_rangeYesThe time range for the top items. Must be "short_term", "medium_term", or "long_term"
limitNoMaximum number of items to return (1-50)
offsetNoThe index of the first item to return. Defaults to 0

Implementation Reference

  • The handler function that executes the tool logic: fetches user's top artists or tracks from Spotify API using currentUser.topItems, handles formatting and empty results.
    handler: async (args, extra: SpotifyHandlerExtra) => {
      const { type, time_range, limit = 50, offset = 0 } = args;
    
      const topItems = await handleSpotifyRequest(async (spotifyApi) => {
        return await spotifyApi.currentUser.topItems(
          type as 'artists' | 'tracks',
          time_range as 'short_term' | 'medium_term' | 'long_term',
          limit as MaxInt<50>,
          offset,
        );
      });
    
      if (topItems.items.length === 0) {
        return {
          content: [
            {
              type: 'text',
              text: `User doesn't have any top ${type} on Spotify`,
            },
          ],
        };
      }
    
      const formattedItems = topItems.items
        .map((item, i) => {
          if (type === 'artists') {
            return `${i + 1}. "${item.name}" - ID: ${item.id}`;
          } else if (
            type === 'tracks' &&
            'artists' in item &&
            Array.isArray(item.artists)
          ) {
            const artists = item.artists.map((a) => a.name).join(', ');
            return `${i + 1}. "${item.name}" by ${artists} - ID: ${item.id}`;
          } else {
            // fallback for type safety
            return `${i + 1}. "${item.name}" - ID: ${item.id}`;
          }
        })
        .join('\n');
    
      return {
        content: [
          {
            type: 'text',
            text: `# Top ${type}\n\n${formattedItems}`,
          },
        ],
      };
    },
  • Input schema using Zod for validating tool parameters: type, time_range, limit, offset.
    schema: {
      type: z
        .string()
        .describe(
          'The type of items to get top for. Must be "artists" or "tracks"',
        ),
      time_range: z
        .string()
        .describe(
          'The time range for the top items. Must be "short_term", "medium_term", or "long_term"',
        ),
      limit: z
        .number()
        .min(1)
        .max(50)
        .optional()
        .describe('Maximum number of items to return (1-50)'),
      offset: z
        .number()
        .optional()
        .describe('The index of the first item to return. Defaults to 0'),
    },
  • src/read.ts:521-529 (registration)
    The tool object is added to the readTools array, which is imported and registered via server.tool() calls in src/index.ts.
    export const readTools = [
      searchSpotify,
      getNowPlaying,
      getUserPlaylists,
      getPlaylistTracks,
      getRecentlyPlayed,
      getFollowedArtists,
      getUserTopItems,
    ];
  • src/index.ts:12-14 (registration)
    Generic registration of all tools from readTools (including getUserTopItems) into the MCP server.
    [...playTools, ...readTools, ...writeTools].forEach((tool) => {
      server.tool(tool.name, tool.description, tool.schema, tool.handler);
    });

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/igorgarbuz/spotify-mcp'

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