Skip to main content
Glama
playback.ts3.11 kB
import type { SpotifyClient } from "../spotify-client.js"; import type { PlaybackState } from "../types.js"; export interface ControlPlaybackParams { action: "play" | "pause" | "next" | "previous" | "seek"; uri?: string; position_ms?: number; } /** * Control playback (play, pause, next, previous, seek) */ export async function controlPlayback( client: SpotifyClient, params: ControlPlaybackParams ): Promise<string> { const { action, uri, position_ms } = params; switch (action) { case "play": if (uri) { await client.put("/me/player/play", { uris: [uri] }); return `Started playing: ${uri}`; } else { await client.put("/me/player/play"); return "Playback resumed"; } case "pause": await client.put("/me/player/pause"); return "Playback paused"; case "next": await client.post("/me/player/next"); return "Skipped to next track"; case "previous": await client.post("/me/player/previous"); return "Skipped to previous track"; case "seek": if (position_ms === undefined) { throw new Error("position_ms is required for seek action"); } await client.put("/me/player/seek", undefined, { position_ms }); return `Seeked to ${Math.floor(position_ms / 1000)} seconds`; default: throw new Error(`Unknown action: ${action}`); } } /** * Get current playback state */ export async function getPlaybackState( client: SpotifyClient ): Promise<PlaybackState | null> { try { const state = await client.get<PlaybackState>("/me/player"); return state; } catch (error) { // 204 No Content means no active playback if (error instanceof Error && error.message.includes("204")) { return null; } throw error; } } /** * Format playback state for display */ export function formatPlaybackState(state: PlaybackState | null): string { if (!state || !state.item) { return "No active playback. Start playing music on Spotify to see playback information."; } const track = state.item; const artists = track.artists.map((a) => a.name).join(", "); const progress = formatDuration(state.progress_ms || 0); const duration = formatDuration(track.duration_ms); const status = state.is_playing ? "▶️ Playing" : "⏸️ Paused"; const lines = [ `**${status}**`, "", `**Track:** ${track.name}`, `**Artist:** ${artists}`, `**Album:** ${track.album.name}`, `**Progress:** ${progress} / ${duration}`, `**Device:** ${state.device.name} (${state.device.type})`, `**Shuffle:** ${state.shuffle_state ? "On" : "Off"}`, `**Repeat:** ${state.repeat_state}`, "", `**URI:** ${track.uri}`, `**Spotify Link:** ${track.external_urls.spotify}`, ]; return lines.join("\n"); } /** * Format duration from milliseconds to MM:SS */ function formatDuration(ms: number): string { const totalSeconds = Math.floor(ms / 1000); const minutes = Math.floor(totalSeconds / 60); const seconds = totalSeconds % 60; return `${minutes}:${seconds.toString().padStart(2, "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/nicklaustrup/mcp-spotify'

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