UNPKG

@pedrocid/music-mcp

Version:

MCP server for controlling Apple Music on macOS (v1.0.5)

135 lines (134 loc) 5.28 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.queueMusicTool = void 0; exports.handleQueueMusic = handleQueueMusic; const logger_js_1 = require("../logger.js"); const config_js_1 = require("../config.js"); const child_process_1 = require("child_process"); const path_1 = require("path"); exports.queueMusicTool = { name: 'queue_music', description: 'Manage music queue and enhanced playlist control', inputSchema: { type: 'object', properties: { action: { type: 'string', enum: ['view_queue', 'add_to_queue', 'play_queue', 'clear_queue', 'play_playlist'], description: 'Queue management action to perform' }, trackSearchTerm: { type: 'string', description: 'Track name or search term (required for add_to_queue)' }, playlistName: { type: 'string', description: 'Name of the playlist (required for play_playlist)' }, shuffle: { type: 'boolean', description: 'Whether to shuffle the playlist (optional for play_playlist)' } }, required: ['action'] } }; async function handleQueueMusic(input) { logger_js_1.logger.info({ action: input.action }, 'Managing music queue'); const config = (0, config_js_1.getConfig)(); try { let result; switch (input.action) { case 'view_queue': result = await executeAppleScript((0, path_1.join)(__dirname, '../scripts/queue/get-queue-info.applescript'), [], config.timeoutSeconds * 1000); break; case 'add_to_queue': if (!input.trackSearchTerm) { return { success: false, message: 'Track search term is required for add_to_queue action', error: 'Missing track search term' }; } result = await executeAppleScript((0, path_1.join)(__dirname, '../scripts/queue/add-to-queue.applescript'), [input.trackSearchTerm], config.timeoutSeconds * 1000); break; case 'play_queue': result = await executeAppleScript((0, path_1.join)(__dirname, '../scripts/queue/play-queue.applescript'), [], config.timeoutSeconds * 1000); break; case 'clear_queue': result = await executeAppleScript((0, path_1.join)(__dirname, '../scripts/queue/clear-queue.applescript'), [], config.timeoutSeconds * 1000); break; case 'play_playlist': if (!input.playlistName) { return { success: false, message: 'Playlist name is required for play_playlist action', error: 'Missing playlist name' }; } const shuffleParam = input.shuffle ? 'true' : 'false'; result = await executeAppleScript((0, path_1.join)(__dirname, '../scripts/playlist/play-playlist.applescript'), [input.playlistName, shuffleParam], config.timeoutSeconds * 1000); break; default: return { success: false, message: `Unknown action: ${input.action}`, error: 'Invalid action' }; } if (result.startsWith('Error')) { return { success: false, message: result, error: result }; } // Try to parse JSON result for view_queue let data; if (input.action === 'view_queue') { try { data = JSON.parse(result); } catch { // If not JSON, return as string data = result; } } else { data = result; } return { success: true, data, message: result }; } catch (error) { const errorMessage = error instanceof Error ? error.message : String(error); logger_js_1.logger.error({ error, action: input.action }, 'Queue management failed'); return { success: false, message: `Queue ${input.action} failed: ${errorMessage}`, error: errorMessage }; } } async function executeAppleScript(scriptPath, args = [], timeout = 30000) { try { // Build the command with properly escaped arguments const quotedArgs = args.map(arg => `"${arg.replace(/"/g, '\\"')}"`).join(' '); const command = `osascript "${scriptPath}" ${quotedArgs}`; const result = (0, child_process_1.execSync)(command, { timeout, encoding: 'utf8', stdio: 'pipe' }); return result.toString().trim(); } catch (error) { if (error.code === 'TIMEOUT') { throw new Error(`AppleScript execution timed out after ${timeout}ms`); } throw new Error(`AppleScript execution failed: ${error.message}`); } }