resolve_music
Resolve any song or album to streaming, digital purchase, or physical media links. Results ranked by trust and availability from major platforms.
Instructions
Find where to stream, buy, or collect a song or album. Returns ranked results covering streaming (Spotify, Apple Music, Tidal, YouTube Music), digital purchase (iTunes, Amazon MP3, Bandcamp), and physical media (vinyl, CD via Amazon, Discogs). Use when a user asks about music — whether they want to listen, own digitally, or find a collector edition. Ranked by trust × price × availability, never by commission.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| slug | Yes | The BeatsVine page slug for the track or album. Format: artist-name-song-title (lowercase, hyphenated). Example: 'ed-sheeran-galway-girl' |
Implementation Reference
- src/tools/resolveMusic.ts:30-72 (handler)Main handler function — calls BeatsVine /[slug]/json, validates response, returns success/error result
export async function resolveMusic(input: ResolveMusicInput): Promise<ResolveMusicResult> { const { slug } = input; const url = `${BEATSVINE_BASE}/${encodeURIComponent(slug)}/json`; try { const res = await fetch(url, { headers: { "User-Agent": "rootvine-mcp/1.0.2", "Accept": "application/json", }, signal: AbortSignal.timeout(5000), // 5s timeout }); if (!res.ok && res.status !== 404) { return { success: false, error: `BeatsVine returned HTTP ${res.status}`, }; } const data = await res.json(); // Validate against v1 schema const validation = validateResponse(data); if (!validation.success) { return { success: false, error: `Response validation failed: ${validation.error.message}`, }; } return { success: true, response: validation.data as RootVineResponseV1, }; } catch (err) { const message = err instanceof Error ? err.message : "Unknown error"; return { success: false, error: `Failed to reach BeatsVine: ${message}`, }; } } - src/tools/resolveMusic.ts:17-25 (schema)Input (ResolveMusicInput) and output (ResolveMusicResult) type definitions for the resolve_music tool
export interface ResolveMusicInput { slug: string; } export interface ResolveMusicResult { success: boolean; response?: RootVineResponseV1; error?: string; } - src/index.ts:48-83 (registration)Tool registration with MCP server — registers 'resolve_music' with description, input schema (slug via zod), and async handler that calls resolveMusic then formats via formatMusicResponse
// Tool: resolve_music // ============================================ server.registerTool( "resolve_music", { description: "Find where to stream, buy, or collect a song or album. Returns ranked results covering streaming (Spotify, Apple Music, Tidal, YouTube Music), digital purchase (iTunes, Amazon MP3, Bandcamp), and physical media (vinyl, CD via Amazon, Discogs). Use when a user asks about music — whether they want to listen, own digitally, or find a collector edition. Ranked by trust × price × availability, never by commission.", inputSchema: { slug: z .string() .describe("The BeatsVine page slug for the track or album. Format: artist-name-song-title (lowercase, hyphenated). Example: 'ed-sheeran-galway-girl'"), }, }, async ({ slug }) => { const result = await resolveMusic({ slug }); if (!result.success || !result.response) { return { content: [ { type: "text" as const, text: `Could not resolve music: ${result.error || "Unknown error"}`, }, ], }; } return { content: [ { type: "text" as const, text: formatMusicResponse(result.response), }, ], }; }, ); - src/tools/resolveMusic.ts:78-137 (helper)Helper function to format the BeatsVine response into a human-readable string with artist, title, cover art, and ranked results with prices and links
export function formatMusicResponse(response: RootVineResponseV1): string { const lines: string[] = []; // Header if (response.query.artist && response.query.title) { lines.push(`🎵 ${response.query.artist} — ${response.query.title}`); } else { lines.push(`🎵 ${response.query.raw}`); } if (response.cover_art) { lines.push(`Cover: ${response.cover_art}`); } lines.push(""); // Status handling if (response.status === "error" && response.error) { lines.push(`❌ Error: ${response.error.message}`); if (response.error.retryable) { lines.push("(This error is retryable)"); } return lines.join("\n"); } if (response.status === "no_results") { lines.push("No results found for this query."); if (response.source_url) { lines.push(`Source: ${response.source_url}`); } return lines.join("\n"); } // Results for (const result of response.results) { const priceStr = result.price ? `${result.price.currency} ${result.price.amount.toFixed(2)}` : result.type === "stream" ? "Free" : "Price unknown"; const link = result.click_url || result.url; // Always prefer click_url lines.push( `${result.rank}. **${result.merchant}** (${result.trust_tier})`, ` ${result.type === "stream" ? "▶️ Stream" : "🛒 Buy"} — ${priceStr}`, ` ${link}`, "", ); } // Warnings if (response.warnings.length > 0) { lines.push(`⚠️ Warnings: ${response.warnings.join(", ")}`); } // Source if (response.source_url) { lines.push(`Source: ${response.source_url}`); } return lines.join("\n"); } - src/tools/findProduct.ts:83-93 (helper)The find_product router calls resolveMusic when category is 'music'
if (category === "music") { const result = await resolveMusic({ slug }); return { success: result.success, category: "music", response: result.response, formatted: result.response ? formatMusicResponse(result.response) : `❌ ${result.error || "Unknown error"}`, error: result.error, };