say-mcp-server
by: bmorphism
MCP server for macOS text-to-speech functionality
📌Overview
Purpose: To provide comprehensive text-to-speech functionality on macOS using the built-in say
command, enabling customized speech capabilities within applications.
Overview: The say-mcp-server
is an MCP server that harnesses macOS's text-to-speech capabilities, allowing users to easily convert text into spoken words with various modulation options. It supports integration with other MCP tools and applications, enhancing the accessibility and usability of audio features.
Key Features:
-
Extensive Customization: Users can manipulate speech parameters such as voice, rate, volume, and emphasis directly through the command arguments, allowing for tailored audio experiences.
-
Dynamic Interactivity: The server allows speech to run in the background while processing other commands, enabling seamless multitasking and enhancing user interactions with various services.
-
Voice Modulation Options: Users can dynamically change aspects like pitch, volume, and speaking rate mid-sentence, enriching the spoken output for a more engaging experience.
-
Integration Friendly: Easily integrates with various other MCP tools (like search functionalities or external content retrieval), augmenting their usability with audio outputs, making it suitable for applications in educational and assistive technology contexts.
say-mcp-server
An MCP server that provides text-to-speech functionality using macOS's built-in say
command.
Requirements
- macOS (uses the built-in
say
command) - Node.js >= 14.0.0
Installation
npm install say-mcp-server
Configuration
Add the following to your MCP settings configuration file:
{
"mcpServers": {
"say": {
"command": "node",
"args": ["/path/to/say-mcp-server/build/index.js"]
}
}
}
Tools
speak
The speak
tool provides access to macOS's text-to-speech capabilities with extensive customization options.
Basic Usage
Use macOS text-to-speech to speak text aloud.
Parameters:
text
(required): Text to speak. Supports:- Plain text
- Basic punctuation for pauses
- Newlines for natural breaks
- [[slnc 500]] for 500ms silence
- [[rate 200]] for changing speed mid-text
- [[volm 0.5]] for changing volume mid-text
- [[emph +]] and [[emph -]] for emphasis
- [[pbas +10]] for pitch adjustment
voice
(optional): Voice to use (default: "Alex")rate
(optional): Speaking rate in words per minute (default: 175, range: 1-500)background
(optional): Run speech in background to allow further MCP interaction (default: false)
Advanced Features
- Voice Modulation:
use_mcp_tool({
server_name: "say",
tool_name: "speak",
arguments: {
text: "[[volm 0.7]] This is quieter [[volm 1.0]] and this is normal [[volm 1.5]] and this is louder",
voice: "Victoria"
}
});
- Dynamic Rate Changes:
use_mcp_tool({
server_name: "say",
tool_name: "speak",
arguments: {
text: "Normal speed [[rate 300]] now speaking faster [[rate 100]] and now slower",
voice: "Fred"
}
});
- Emphasis and Pitch:
use_mcp_tool({
server_name: "say",
tool_name: "speak",
arguments: {
text: "[[emph +]] Important point! [[emph -]] [[pbas +10]] Higher pitch [[pbas -10]] Lower pitch",
voice: "Samantha"
}
});
Integration Examples
- With Marginalia Search:
const searchResult = await use_mcp_tool({
server_name: "marginalia-mcp-server",
tool_name: "search",
arguments: { query: "quantum computing basics", count: 1 }
});
await use_mcp_tool({
server_name: "say",
tool_name: "speak",
arguments: {
text: searchResult.results[0].description,
voice: "Daniel",
rate: 150
}
});
- With YouTube Transcripts:
const transcript = await use_mcp_tool({
server_name: "youtube-transcript",
tool_name: "get_transcript",
arguments: {
url: "https://youtube.com/watch?v=example",
lang: "en"
}
});
await use_mcp_tool({
server_name: "say",
tool_name: "speak",
arguments: {
text: transcript.text,
voice: "Samantha",
rate: 175
}
});
- Background Speech with Multiple Actions:
await use_mcp_tool({
server_name: "say",
tool_name: "speak",
arguments: {
text: "This is a long speech that will run in the background...",
voice: "Rocko (Italian (Italy))",
rate: 69,
background: true
}
});
await use_mcp_tool({
server_name: "marginalia-mcp-server",
tool_name: "search",
arguments: { query: "parallel processing" }
});
- With Apple Notes:
const notes = await use_mcp_tool({
server_name: "apple-notes-mcp",
tool_name: "search-notes",
arguments: { query: "meeting notes" }
});
if (notes.length > 0) {
await use_mcp_tool({
server_name: "say",
tool_name: "speak",
arguments: {
text: notes[0].content,
voice: "Karen",
rate: 160
}
});
}
Example call:
use_mcp_tool({
server_name: "say",
tool_name: "speak",
arguments: {
text: "Hello, world!",
voice: "Victoria",
rate: 200
}
});
list_voices
List all available text-to-speech voices on the system.
Example:
use_mcp_tool({
server_name: "say",
tool_name: "list_voices",
arguments: {}
});
Recommended Voices
Voice | Language/Region | Intellectual Figure | CLI Specification |
---|---|---|---|
Anna (Premium) | German | Emmy Noether | -v "Anna (Premium)" |
Emma (Premium) | Italian | Maria Adelaide Sneider | -v "Emma (Premium)" |
Federica (Premium) | Italian | Pia Nalli | -v "Federica (Premium)" |
Serena (Premium) | English (UK) | Bertha Swirles | -v "Serena (Premium)" |
Petra (Premium) | German | Ruth Moufang | -v "Petra (Premium)" |
Yuna (Premium) | Korean | Hee Oh | -v "Yuna (Premium)" |
Alva (Premium) | Swedish | Sonja Korovkin | -v "Alva (Premium)" |
Amélie (Premium) | French (Canada) | Sophie Germain | -v "Amélie (Premium)" |
Ewa (Premium) | Polish | Maria Wielgus | -v "Ewa (Premium)" |
Kiyara (Premium) | Hindi | Shakuntala Devi | -v "Kiyara (Premium)" |
Majed (Premium) | Arabic | Maha Al-Aswad | -v "Majed (Premium)" |
Tünde (Premium) | Hungarian | Julia Erdős | -v "Tünde (Premium)" |
Fiona (Enhanced) | English (Scottish) | Mary Somerville | -v "Fiona (Enhanced)" |
Lesya (Enhanced) | Ukrainian | Olena Voinova | -v "Lesya (Enhanced)" |
Carmit (Enhanced) | Hebrew | Tali Seror | -v "Carmit (Enhanced)" |
Milena (Enhanced) | Russian | Olga Ladyzhenskaya | -v "Milena (Enhanced)" |
Katya (Enhanced) | Russian | Sofia Kovalevskaya | -v "Katya (Enhanced)" |
Damayanti (Enhanced) | Indonesian | Sri Pekerti | -v "Damayanti (Enhanced)" |
Dariush (Enhanced) | Persian | Maryam Mirzakhani | -v "Dariush (Enhanced)" |
Rocko (Italian) | Italian | Astro Boy (Tetsuwan Atomu) Italian dub | -v "Rocko (Italian (Italy))" |
Binbin (Enhanced) | Chinese (Mainland) | Li Shanlan | -v "Binbin (Enhanced)" |
Han (Premium) | Chinese (Mainland) | Chen Jingrun | -v "Han (Premium)" |
Lilian (Premium) | Chinese (Mainland) | Hua Luogeng | -v "Lilian (Premium)" |
Meijia | Chinese (Taiwan) | Sun-Yung Alice Chang | -v "Meijia" |
Sinji (Premium) | Chinese (Hong Kong) | Shing-Tung Yau | -v "Sinji (Premium)" |
Tingting | Chinese (Mainland) | Wang Zhenyi | -v "Tingting" |
Yue (Premium) | Chinese (Mainland) | Chern Shiing-shen | -v "Yue (Premium)" |
Contributors
- Barton Rhodes - barton@vibes.lol
License
MIT