UNPKG

@chinchillaenterprises/mcp-ai-assistant

Version:

MCP server for AI assistant with ElevenLabs text-to-speech integration

114 lines (95 loc) â€ĸ 3.25 kB
#!/usr/bin/env node const axios = require('axios'); const fs = require('fs'); const path = require('path'); const { exec } = require('child_process'); const API_KEY = process.env.ELEVENLABS_API_KEY; // Check if API key is set if (!API_KEY) { console.error('❌ ELEVENLABS_API_KEY environment variable is required'); console.error('📝 Set your API key: export ELEVENLABS_API_KEY="your-key-here"'); process.exit(1); } // Available voices const VOICES = { 'sarah': 'EXAVITQu4vr4xnSDxMaL', 'aria': '9BWtsMINqrJLrRacOk9x', 'laura': 'FGY2WhTYpPnrIDTdsKH5', 'charlie': 'IKne3meq5aSn9XLyUdCD', 'george': 'JBFqnCBsd6RMkjVDRZzb' }; async function speak(text, voiceName = 'sarah') { const voiceId = VOICES[voiceName.toLowerCase()] || VOICES.sarah; const timestamp = new Date().toISOString().replace(/[:.]/g, '-'); const outputPath = path.join(__dirname, 'audio', `claude-${timestamp}.mp3`); console.log(`đŸŽ™ī¸ Using voice: ${voiceName} (${voiceId})`); console.log('📝 Converting text to speech...'); try { // Ensure audio directory exists const audioDir = path.join(__dirname, 'audio'); if (!fs.existsSync(audioDir)) { fs.mkdirSync(audioDir, { recursive: true }); } // Call ElevenLabs API const response = await axios.post( `https://api.elevenlabs.io/v1/text-to-speech/${voiceId}`, { text: text, model_id: 'eleven_monolingual_v1', voice_settings: { stability: 0.5, similarity_boost: 0.5 } }, { headers: { 'Accept': 'audio/mpeg', 'xi-api-key': API_KEY, 'Content-Type': 'application/json' }, responseType: 'stream' } ); // Save audio file const writer = fs.createWriteStream(outputPath); response.data.pipe(writer); await new Promise((resolve, reject) => { writer.on('finish', resolve); writer.on('error', reject); }); console.log(`✅ Audio saved to: ${outputPath}`); // Try to play on macOS if (process.platform === 'darwin') { console.log('🔊 Playing audio...'); // Return a promise that resolves when playback completes return new Promise((resolve) => { exec(`afplay "${outputPath}"`, (error) => { if (error) { console.log('â„šī¸ Couldn\'t auto-play. Use any audio player to play:', outputPath); } else { console.log('✅ Playback complete!'); } resolve(); }); }); } else { console.log('â„šī¸ Audio file saved. Play it with your favorite audio player!'); } } catch (error) { console.error('❌ Error:', error.response?.data?.detail?.message || error.message); } } // Command line usage if (require.main === module) { const args = process.argv.slice(2); if (args.length === 0) { console.log('Usage: node speak.js "Your text here" [voice]'); console.log('Available voices:', Object.keys(VOICES).join(', ')); console.log('Example: node speak.js "Hello world" sarah'); process.exit(1); } const text = args[0]; const voice = args[1] || 'sarah'; speak(text, voice); } module.exports = { speak };