search-tracks
Search for Spotify tracks using a query and specify the number of results to return. Integrates with the Spotify MCP Server to provide accurate track listings for playlist creation or recommendations.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Number of results to return | |
| query | Yes | Search query for tracks |
Implementation Reference
- mcp/spotify-mcp.ts:184-242 (handler)The handler function for the search-tracks tool, which performs the Spotify API search for tracks based on the query and limit, processes the response, and returns formatted track data or error messages.async ({ query, limit }) => { try { const accessToken = await getValidAccessToken(); const response = await fetch( `https://api.spotify.com/v1/search?q=${encodeURIComponent( query )}&type=track&limit=${limit}`, { headers: { Authorization: `Bearer ${accessToken}`, }, } ); const data = (await response.json()) as any; if (!response.ok) { return { content: [ { type: "text", text: `Error searching tracks: ${JSON.stringify(data)}`, }, ], isError: true, }; } const tracks = data.tracks.items.map((track: any) => ({ id: track.id, name: track.name, artist: track.artists.map((artist: any) => artist.name).join(", "), album: track.album.name, uri: track.uri, })); return { content: [ { type: "text", text: JSON.stringify(tracks, null, 2), }, ], }; } catch (error) { return { content: [ { type: "text", text: `Failed to search tracks: ${ error instanceof Error ? error.message : String(error) }`, }, ], isError: true, }; } }
- mcp/spotify-mcp.ts:176-183 (schema)Zod schema defining the input parameters for the search-tracks tool: query (string) and optional limit (number, 1-50, default 10).query: z.string().describe("Search query for tracks"), limit: z .number() .min(1) .max(50) .default(10) .describe("Number of results to return"), },
- mcp/spotify-mcp.ts:174-243 (registration)The server.tool call registering the search-tracks tool with its name, input schema, and handler function."search-tracks", { query: z.string().describe("Search query for tracks"), limit: z .number() .min(1) .max(50) .default(10) .describe("Number of results to return"), }, async ({ query, limit }) => { try { const accessToken = await getValidAccessToken(); const response = await fetch( `https://api.spotify.com/v1/search?q=${encodeURIComponent( query )}&type=track&limit=${limit}`, { headers: { Authorization: `Bearer ${accessToken}`, }, } ); const data = (await response.json()) as any; if (!response.ok) { return { content: [ { type: "text", text: `Error searching tracks: ${JSON.stringify(data)}`, }, ], isError: true, }; } const tracks = data.tracks.items.map((track: any) => ({ id: track.id, name: track.name, artist: track.artists.map((artist: any) => artist.name).join(", "), album: track.album.name, uri: track.uri, })); return { content: [ { type: "text", text: JSON.stringify(tracks, null, 2), }, ], }; } catch (error) { return { content: [ { type: "text", text: `Failed to search tracks: ${ error instanceof Error ? error.message : String(error) }`, }, ], isError: true, }; } } );
- mcp/spotify-mcp.ts:22-79 (helper)Helper function used by the handler to obtain a valid Spotify access token, automatically refreshing it if expired.async function getValidAccessToken() { if (!spotifyAuthInfo.accessToken || !spotifyAuthInfo.refreshToken) { throw new Error( "No access token available. Please set credentials first using the set-spotify-credentials tool." ); } try { // Try using current token const response = await fetch("https://api.spotify.com/v1/me", { headers: { Authorization: `Bearer ${spotifyAuthInfo.accessToken}`, }, }); // If token works, return it if (response.ok) { return spotifyAuthInfo.accessToken; } console.error("Access token expired, refreshing..."); // If token doesn't work, refresh it const refreshResponse = await fetch( "https://accounts.spotify.com/api/token", { method: "POST", headers: { "Content-Type": "application/x-www-form-urlencoded", Authorization: "Basic " + Buffer.from( spotifyAuthInfo.clientId + ":" + spotifyAuthInfo.clientSecret ).toString("base64"), }, body: new URLSearchParams({ grant_type: "refresh_token", refresh_token: spotifyAuthInfo.refreshToken, }), } ); const data = (await refreshResponse.json()) as any; if (data.access_token) { console.error("Successfully refreshed access token"); spotifyAuthInfo.accessToken = data.access_token; return spotifyAuthInfo.accessToken; } throw new Error("Failed to refresh access token"); } catch (error) { throw new Error( "Error with access token: " + (error instanceof Error ? error.message : String(error)) ); } }