Skip to main content
Glama
client.ts5.1 kB
import SpotifyWebApi from 'spotify-web-api-node'; import { SpotifyAuth } from './auth.js'; import type { PlaylistInfo, SearchResult } from '../types.js'; export class SpotifyClient { private auth: SpotifyAuth; constructor(auth: SpotifyAuth) { this.auth = auth; } private async getApi(): Promise<SpotifyWebApi> { await this.auth.ensureValidToken(); return this.auth.getApi(); } async getCurrentUserPlaylists(): Promise<PlaylistInfo[]> { const api = await this.getApi(); const data = await api.getUserPlaylists(); return data.body.items.map((playlist: any) => ({ id: playlist.id, name: playlist.name, uri: playlist.uri, })); } async findPlaylistByName(name: string): Promise<PlaylistInfo | null> { const playlists = await this.getCurrentUserPlaylists(); const normalizedName = name.toLowerCase().trim(); const playlist = playlists.find(p => p.name.toLowerCase().includes(normalizedName) || normalizedName.includes(p.name.toLowerCase()) ); return playlist || null; } async searchTracks(query: string, limit: number = 10) { const api = await this.getApi(); const data = await api.searchTracks(query, { limit }); return data.body.tracks?.items.map((track: any) => ({ id: track.id, name: track.name, artist: track.artists[0]?.name || 'Unknown', uri: track.uri, album: track.album.name, })) || []; } async searchAlbums(query: string, limit: number = 10) { const api = await this.getApi(); const data = await api.searchAlbums(query, { limit }); return data.body.albums?.items.map((album: any) => ({ id: album.id, name: album.name, artist: album.artists[0]?.name || 'Unknown', uri: album.uri, })) || []; } async searchArtists(query: string, limit: number = 10) { const api = await this.getApi(); const data = await api.searchArtists(query, { limit }); return data.body.artists?.items.map((artist: any) => ({ id: artist.id, name: artist.name, uri: artist.uri, })) || []; } async search(query: string, limit: number = 10): Promise<SearchResult> { const api = await this.getApi(); const [tracksData, albumsData, artistsData] = await Promise.all([ api.searchTracks(query, { limit }), api.searchAlbums(query, { limit }), api.searchArtists(query, { limit }), ]); return { tracks: tracksData.body.tracks?.items.map((track: any) => ({ id: track.id, name: track.name, artist: track.artists[0]?.name || 'Unknown', uri: track.uri, })) || [], albums: albumsData.body.albums?.items.map((album: any) => ({ id: album.id, name: album.name, artist: album.artists[0]?.name || 'Unknown', uri: album.uri, })) || [], artists: artistsData.body.artists?.items.map((artist: any) => ({ id: artist.id, name: artist.name, uri: artist.uri, })) || [], }; } async playPlaylist(playlistUri: string, deviceId?: string) { const api = await this.getApi(); await api.play({ context_uri: playlistUri, device_id: deviceId, }); } async playAlbum(albumUri: string, deviceId?: string) { const api = await this.getApi(); await api.play({ context_uri: albumUri, device_id: deviceId, }); } async playTrack(trackUri: string, deviceId?: string) { const api = await this.getApi(); await api.play({ uris: [trackUri], device_id: deviceId, }); } async pause(deviceId?: string) { const api = await this.getApi(); await api.pause({ device_id: deviceId }); } async resume(deviceId?: string) { const api = await this.getApi(); await api.play({ device_id: deviceId }); } async skipToNext(deviceId?: string) { const api = await this.getApi(); await api.skipToNext({ device_id: deviceId }); } async skipToPrevious(deviceId?: string) { const api = await this.getApi(); await api.skipToPrevious({ device_id: deviceId }); } async setVolume(volumePercent: number, deviceId?: string) { const api = await this.getApi(); await api.setVolume(volumePercent, { device_id: deviceId }); } async getCurrentlyPlaying() { const api = await this.getApi(); const data = await api.getMyCurrentPlayingTrack(); if (!data.body.item) { return null; } const track = data.body.item as any; return { name: track.name, artist: track.artists[0]?.name || 'Unknown', album: track.album?.name || 'Unknown', uri: track.uri, isPlaying: data.body.is_playing, progressMs: data.body.progress_ms || 0, }; } async getDevices() { const api = await this.getApi(); const data = await api.getMyDevices(); return data.body.devices.map((device: any) => ({ id: device.id, name: device.name, type: device.type, isActive: device.is_active, volumePercent: device.volume_percent || 0, })); } }

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